在不重新启动整个 JVM 的情况下将新代码推送到生产环服务器的最佳方法是什么?
目前我在生产中使用 wrap-reload ,但这对我来说不太适用,因为有时我想在环开始使用新代码处理请求之前在 repl 中运行命令(例如进行数据库迁移)。还有各种博客和教程说不要在生产中使用 wrap-reload,尽管我不明白为什么不这样做。
我提出了以下解决方案,但我承认我对幕后发生的事情没有深入的了解。我想知道我是否可以让这样做的人进行健全性检查。这种技术看起来合理吗?
这个想法是有一个路径 (/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))