【问题标题】:Reloading code on a production ring-clojure server在生产 ring-clojure 服务器上重新加载代码
【发布时间】:2012-04-16 18:07:18
【问题描述】:

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

目前我在生产环境中使用 wrap-reload,但这对我来说不太适用,因为有时我想在 ring 开始使用新代码处理请求之前在 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))

【问题讨论】:

    标签: clojure ring


    【解决方案1】:

    您拥有的代码将可以工作,但您应该知道:reload-all 只加载一个命名空间并且命名空间依赖项。它不会递归加载 那些 命名空间的依赖项。

    我应该补充一点,在生产系统中强烈不建议以这种方式重新加载。

    新部署的代码可能会出现在系统重新启动之前不明显的错误(例如,它们依赖于仍在运行系统中定义但其声明已被删除的 var)。系统会正常工作,但重启后会失败。

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

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

    【讨论】:

      【解决方案2】:

      在以前的工作中,我有一个使用 common lisp 的 Intranet Web 服务,所以我不知道这是否符合生产条件。此外,在 CL 中,我的答案既不是环也不是 clojure 特定的。不过,它对于重新加载代码很有用。

      我所做的是在生产 lisp 实例上启动一个 swank 服务器(粘液的一部分),甚至从我的桌面远程连接到它。这样我就可以编写新代码、重写代码、调试、重新加载等。显然,在真正的生产系统中你必须格外小心。

      你可以在 clojure 中做类似的事情,你甚至还有 swank 的替代品,比如 nrepl。

      您还必须考虑安全性,并且只允许本地连接,或者任何适合您的方式。

      【讨论】:

      • 我对替代解决方案也很感兴趣。我想大多数东西都会比你在 Java 中的更好(OSGi 有人吗?)
      • 我为我的中间层 Java 服务器做了类似的事情。我一直在考虑尝试将 repl 与 JMX 结合使用。我认为通过一些技巧应该可以通过 JMX 路由所有 nrepl 流量,按顺序可以通过 SSL 和身份验证进行保护。
      猜你喜欢
      • 1970-01-01
      • 2020-03-08
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 2016-09-03
      • 1970-01-01
      • 2013-01-24
      相关资源
      最近更新 更多