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

欢迎!请参阅关于页面以了解如何进行操作的更多信息。

+1投票
命名空间与变量
编辑

我在服务器上直接从git仓库运行我的Clojure应用程序,使用Clojure CLI。我遇到了一个问题,虚拟服务器上启动需要约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)

如果您能交互式地查看控制台以确定“慢”的加载发生的位置,这确实是一个不错的建议。否则,可能只是一个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投票

很可能您在启动时加载了某个东西,它有一个顶层def“执行工作”,可能是网络工作,在虚拟服务器环境中耗时较长。通常顶层def初始化数据库连接等问题是问题 - 要么在代码中构造它们,要么使用delay延迟构造直到使用。

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

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

0投票

您能检查到 clojure 命令的任何输出吗?例如,它在其他服务器下载依赖项时生成的输出,例如从 Clojars.org 或 Maven central?

在系统启动缓慢的地方,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)
...