gpt4 book ai didi

clojure - 在生产环形Clojure服务器上重新加载代码

转载 作者:行者123 更新时间:2023-12-04 03:59:47 24 4
gpt4 key购买 nike

在不重新启动整个JVM的情况下将新代码推送到生产环型服务器的最佳方法是什么?

目前,我在生产环境中使用wrap-reload,但是这对我来说并不奏效,因为有时我想在ring开始使用新代码处理请求之前,在repl中运行命令(例如,进行数据库迁移)。还有各种各样的博客和教程都说不要在生产中使用包装重载,尽管我不明白为什么不这样做。

我已经提出了以下解决方案,但是我承认我对幕后发生的事情没有深刻的了解。我想知道我是否可以得到这样做的人的健全性检查。这种技术看起来合理吗?

这个想法是要有一个路径(/admin/reload-clj)导致所有clojure代码都被重新加载。

(defonce ^:dynamic *jetty*)
(declare reload-clj)

(defn app [req]
...
(when (= (req :uri) "/admin/reload-clj") (reload-clj req))
...)

(defn start-jetty []
(let [j (run-jetty app {:port (http-port) :join? false :max-threads 16})]
(dosync (ref-set *jetty* j))
j))

(defn reload-clj [req]
(future
(log/info "Reloading clojure code...")
(require '(whrusrv admin main utils wdb) :reload-all)
(.stop @*jetty*)
(start-jetty)
(log/info "Clojure reload success!"))
{:status 200
:headers {"Content-Type" "text/plain"}
:body "Reloading..."})

(defn -main [& args]
(start-jetty))

最佳答案

尽管您应该知道:reload-all仅加载一个 namespace 以及该 namespace 的依赖关系,但是您拥有的代码将起作用。它不会递归地加载那些 namespace 的依赖性。

我应该补充一点,在生产系统中强烈建议不要以这种方式进行重装。

新部署的代码可能会出现错误,直到重新启动系统后才能发现这些错误(例如,它们依赖于仍在运行的系统中定义但已删除其声明的var)。系统将正常运行,但重新启动后将失败。

加载代码还可能产生副作用,这可能会破坏您的生产环境。尽管避免这种情况的好方法,但真正确保不会发生意外情况的唯一方法是重新启动JVM。

在JVM上进行零停机时间部署的最佳方法是使用负载平衡器进行滚动部署。

关于clojure - 在生产环形Clojure服务器上重新加载代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9987300/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com