请在 2024 Clojure 状态调查! 中分享您的想法。

欢迎!有关如何使用本站,请参阅 关于 页面以获取更多信息。

+1
命名空间和变量
编辑

我在服务器上直接从 git 仓库使用 Clojure CLI 运行我的 Clojure 应用程序。我遇到一个问题,在虚拟服务器上启动耗时约为 5-25 分钟,在我的笔记本电脑上启动耗时约为 1 分钟。在这段时间里,CPU 使用率几乎为零,仅使用了 4GB 内存中的一部分。我在想这是否是某种锁定条件。这似乎可能与某个依赖项有关,因为我以前从未遇到过这种情况。有哪些方法可以诊断出问题呢?

$ time clojure -A:server -e "(require 'riverdb.server)"
WARNING: requiring-resolve already refers to: #'clojure.core/requiring-resolve in namespace: datomic.common, being replaced by: #'datomic.common/requiring-resolve
    
real	24m49.555s
user	1m58.976s
sys	0m3.672s

我尝试了 https://clojure.org/guides/dev_startup_time 中的解决方案,我觉得这有所帮助,但如果多次运行,延迟会有很大的变化。

$ time clojure -A:dev:server -e "(require 'riverdb.server)"

real	5m19.167s
user	0m29.084s
sys	0m1.724s

$ time clojure -A:dev:server -e "(require 'riverdb.server)"

real	19m53.558s
user	0m31.972s
sys	0m1.988s

3 个答案

+1

选中
 
最佳答案

尝试 (require 'riverdb.server :verbose)

by
如果您能够交互式地监控控制台以确定“缓慢”的加载位置,这是一个不错的选择。否则,可能只是 ns 列表,因此并不很有帮助。
by
编辑 by
这真是一个我不知道的绝佳选项!它卡在了
    (clojure.core/load "/buddy/core/keys/jwk/ec")

将 buddy/buddy-core 从 1.6 版本降级到 1.4 版本消除了问题。

here: https://github.com/funcool/buddy-core/issues/70

Buddy 在加载命名空间时生成密钥时会“做工作”,这会耗尽虚拟服务器的熵,所以解决办法是这样的

time clojure -A:server -J-Djava.security.egd=file:/dev/urandom -e "(require 'riverdb.server :verbose)"
+1
by

可能是您启动时加载了某些具有顶级 def 的内容,“执行工作”,可能是虚拟服务器环境中耗时较长的网络工作。初始化数据库连接等内容的顶级定义通常是问题所在 - 要么在代码中进行构造,要么使用 delay 进行延迟构造。

要调试出现此问题的内容,您需要获取堆栈跟踪。通常在 Java 中,您可以使用 jps 和 jstack 来查找并诱导 JVM 生成堆栈。

如果您不能交互式地查看它,您可以在加载的内容中添加一些顶级代码以调用 (Thread/dumpStack)。或者,您可以在循环中启动一个后台线程来执行此操作(在 Thread/sleep 之间)。

0

您能否查看clojure命令的输出,例如它在从其他服务器(例如Clojars.org或Maven central)下载依赖项时的输出类型?这是一个猜测,但某些版本的clojure命令与某些类型的依赖项存在性能问题。

在系统启动速度慢的情况下,clojure -Sdescribe的输出是什么?这是一个长期的猜测,但以前版本的clojure命令在某些类型的依赖项上存在性能问题。

该问题与Java 8(u202+)、Java 11.0.2和Clojure < 1.10.1有关,并且您正在加载user.clj文件。如果您没有加载user.clj文件,那么这不太可能是问题所在。
$ clojure -Sdescribe
{:version "1.10.1.536"
 :config-files ["/usr/local/lib/clojure/deps.edn" "/home/riverdb/.clojure/deps.edn" "deps.edn" ]
 :config-user "/home/riverdb/.clojure/deps.edn"
 :config-project "deps.edn"
 :install-dir "/usr/local/lib/clojure"
 :config-dir "/home/riverdb/.clojure"
 :cache-dir ".cpcache"
 :force false
 :repro false
 :resolve-aliases ""
 :classpath-aliases ""
 :jvm-aliases ""
 :main-aliases ""
 :all-aliases ""}

$ java -version
openjdk version "11.0.7" 2020-04-14
OpenJDK Runtime Environment GraalVM CE 20.1.0 (build 11.0.7+10-jvmci-20.1-b02)
OpenJDK 64-Bit Server VM GraalVM CE 20.1.0 (build 11.0.7+10-jvmci-20.1-b02, mixed mode, sharing)
...