2024 State of Clojure调查!中分享您的想法。

欢迎!请查看关于页面以了解更多有关该操作的信息。

+1
Namespaces and vars
编辑

我在服务器上直接从git仓库使用clojure CLI运行我的clojure应用。我在虚拟服务器上启动时遇到了一个问题,大概耗时5-25分钟,而在我笔记本电脑上只需约1分钟。在这段时间里,CPU使用率几乎为零,4GB的RAM中几乎没有被使用。我觉得这可能是一种锁定条件。看起来这很可能与一个依赖项有关,因为我以前从未遇到过这种情况。有哪些方法可以诊断出问题所在?

$ 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)

如果您可以交互式监视控制台以确定“缓慢”加载发生的地方,这是一个很好的建议。否则,这可能只是一个ns列表,所以帮助不大。

编辑
哦,这是一个我不了解的绝佳选项!它卡在了
    (clojure.core/load "/buddy/core/keys/jwk/ec")

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

这里有一个问题票据: 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)。或者您可以在循环中创建一个后台线程(线程/sleep之间)来做这件事。

0
by

是否有来自clojure命令的输出您可以进行检查,例如,当它从其他服务器(如Clojars.org或Maven central)下载依赖项时产生的输出类型?

系统上事物运行缓慢时,clojure -Sdescribe的输出是什么?这是一个长远的猜测,但有些旧的clojure命令在某些类型的依赖项上存在性能问题。

by
那是Java 8 (u202+)、Java 11.0.2和Clojure < 1.10.1的问题,并且您正在加载user.clj。如果您没有加载user.clj文件,那么这个问题不太可能。
by
$ 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 版本 "11.0.7" 2020-04-14
OpenJDK 运行时环境 GraalVM CE 20.1.0 (构建 11.0.7+10-jvmci-20.1-b02)
OpenJDK 64 位服务器 VM GraalVM CE 20.1.0 (构建 11.0.7+10-jvmci-20.1-b02,混合模式,共享)
...