Перезагрузка кода на производственном кольцевом сервере - PullRequest
8 голосов
/ 03 апреля 2012

Каков наилучший способ отправить новый код на производственный кольцевой сервер без перезапуска всей JVM?

В настоящее время я использую wrap-reload в производственном процессе, но это не совсем подходит для меня, потому что иногда я хочувыполнить команды в repl (например, выполнить миграцию базы данных) до того, как ring начнет обрабатывать запросы с новым кодом.Также в различных блогах и учебных руководствах говорится, что не следует использовать 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))

Ответы [ 2 ]

6 голосов
/ 07 сентября 2012

Код, который у вас есть, будет работать, хотя вы должны знать, что :reload-all загружает только пространство имен и зависимости пространств имен. Он не рекурсивно загружает зависимости этих пространств имен.

Я должен добавить, что такая перезагрузка настоятельно не рекомендуется в производственной системе.

В новом развернутом коде могут быть ошибки, которые не видны до перезапуска системы (например, они зависят от переменной, которая все еще определяется в работающей системе, но объявление которой было удалено). Система будет работать нормально, но при перезагрузке произойдет сбой.

Загрузка кода также может иметь побочные эффекты, которые могут испортить вашу производственную среду. Хотя это хороший способ избежать этого, единственный способ по-настоящему убедиться, что чего-то неожиданного не произойдет, - это перезапустить JVM.

Лучший способ выполнить развертывание с нулевым временем простоя на JVM - это скользящее развертывание с использованием балансировщика нагрузки.

2 голосов
/ 03 апреля 2012

На предыдущей работе у меня был общий веб-сервис интрасети, поэтому я не знаю, считается ли это производственным.Кроме того, находясь в CL, мой ответ не является специфическим ни для звонка, ни для clojure.Тем не менее, это полезно для перезагрузки кода.

Что я сделал, так это запустил swank-сервер (часть slime) в экземпляре lisp и подключился к нему даже удаленно со своего рабочего стола.Таким образом, я мог бы написать новый код, переписать код, отладить, перезагрузить и т. Д. Очевидно, вам придется быть очень осторожным в реальной производственной системе.

Вы можете сделать то же самое в clojure, у вас даже есть альтернативы swank, такие как nrepl.

Вам также нужно будет учитывать безопасность и разрешать только локальные соединения, или все, что вам подходит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...