2012-04-03 6 views
8

전체 JVM을 다시 시작하지 않고 프로덕션 링 서버로 새 코드를 푸시하는 가장 좋은 방법은 무엇입니까?프로덕션 링 - 클로저 서버에서 코드 다시 로딩

현재 프로덕션에서는 wrap-reload를 사용합니다. 그러나 링이 새로운 코드로 요청을 처리하기 전에 repl (예 : 데이터베이스 마이그레이션)에서 명령을 실행하려고하기 때문에 이것은 나에게 적합하지 않습니다. 또한 다양한 블로그와 튜토리얼은 생산에 wrap-reload를 사용하지 않는다고 설명합니다.

나는 다음과 같은 해결책을 생각해 냈지만, 나는 두포에서 무슨 일이 벌어지고 있는지 깊이 이해하지 못했다고 고백한다. 나는 누군가가 정신 건강 검사를받을 수 있는지 궁금해하고있었습니다. 이 기술이 합리적인 것처럼 보이나요?

아이디어는 모든 clojure 코드가 다시로드되도록하는 경로 (/ admin/reload-clj)를 갖는 것입니다.

(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)) 

답변

6

코드는 작동하지만, :reload-all은 네임 스페이스와 그 네임 스페이스 종속성 만로드한다는 점에 유의해야합니다. 재귀 적으로 종속성을로드하지 않습니다 네임 스페이스.

이 방법으로 다시로드하는 작업은 프로덕션 시스템에서 강력하게 권장하지 않는다는 것을 추가해야합니다.

새로 배포 된 코드는 시스템을 다시 시작할 때까지는 분명하지 않은 오류가있을 수 있습니다 (예 : 실행중인 시스템에서 정의되었지만 선언이 제거 된 var에 의존하는 오류). 시스템은 정상적으로 작동하지만 다시 시작할 때 실패합니다.

로딩 코드에는 생산 환경을 망칠 수있는 부작용이있을 수도 있습니다. 이것들을 피하는 좋은 스타일이지만 예상치 못한 일이 발생하지 않을 것이라는 확신을주는 유일한 방법은 JVM 재시작을하는 것입니다.

JVM에서 제로 다운 타임 배포를 수행하는 가장 좋은 방법은로드 밸런서를 사용하는 롤링 배포입니다.

+1

설명을 주셔서 감사합니다. –

2

이전 작업에서 인트라넷 웹 서비스가 공통 리스프 였기 때문에 프로덕션 자격이되는지는 알 수 없습니다. 또한, CL에 내 대답은 고리도 clojure 특정되지 않습니다. 그래도 코드를 다시로드하는 데 유용합니다.

내가 한 것은 생산 용 lisp 인스턴스에서 실 모양 부분 (slime)의 일부를 시작하여 내 데스크탑에서 원격으로 연결하는 것입니다. 그렇게하면 새로운 코드를 작성하고, 코드를 다시 작성하고, 디버그하고, 다시로드 할 수 있습니다. 실제 프로덕션 시스템에서 추가적으로주의를 기울여야합니다.

당신도 clojure에서 할 수 있습니다. nrepl과 같이 swank에 대한 대안이 있습니다.

보안을 고려하여 로컬 연결 만 허용하거나 어떤 방식 으로든 작동하도록하십시오.

+0

나는 대체 솔루션에도 관심이 많습니다. 내 생각에 대부분의 것들이 자바에서 가지고있는 것보다 낫을 것 같다. (OSGi anybody?) – ivant

+0

나는 중간 계층 Java 서버와 비슷한 것을한다. 나는 JMX와 함께 repl를 시도하는 것을 고려 해왔다. 어떤 속임수로 모든 nrepl 트래픽을 JMX를 통해 라우팅 할 수 있어야한다고 생각합니다. JMX는 SSL 인증과 인증으로 보호 될 수 있습니다. –