守护基于JVM的应用程序
部署體系結構設計是任何定制服務器端應用程序開發項目的重要組成部分。 由于其重要性,部署架構設計應盡早開始,并與其他開發活動一起進行。 部署體系結構設計的復雜性取決于許多方面,包括所提供服務的可伸縮性和可用性目標,部署過程以及系統體系結構的技術屬性。
可服務性和操作問題,例如部署安全性,監視,備份/還原等,與部署體系結構設計的更廣泛主題有關。 這些問題本質上是跨領域的,可能需要從服務推出過程到實際系統管理詳細信息的不同層次上加以解決。
在系統管理詳細信息級別,使用純基于JVM的應用程序部署模型時(在類似Unix的平臺上),經常會遇到以下挑戰:
- 如何安全關閉應用服務器或應用程序? 通常,使用偵聽關閉請求的TCP偵聽器線程。 如果您在同一主機上部署了同一應用服務器的許多實例,則有時很容易混淆這些實例并關閉錯誤的實例。 另外,您還必須防止未經授權訪問關機監聽器。
- 創建與系統啟動和關閉機制(例如Sys-V init,systemd,Upstart等)無縫集成的初始化腳本
- 如果應用程序死了,如何自動重啟?
- 日志文件管理。 應用程序日志可以通過日志庫進行管理(例如,旋轉,壓縮,刪除)。 有時也可以使用日志庫來管理應用服務器或平臺日志,但有時可能需要與OS級工具(例如logrotate)集成。
對于這些問題,有兩種解決方案可以使操作系統與應用程序/應用程序服務器之間的集成更加緊密。 一種廣泛使用的通用解決方案是Java Service Wrapper 。 Java Service Wrapper擅長解決上述挑戰,并根據專有許可發布。 還提供了基于GPL v2的社區許可選項。
Apache commons守護程序是另一個選擇。 它的根源是Apache Tomcat,并且與應用服務器很好地集成在一起,但是它比這要通用得多。除了Java,commons守護程序還可以與其他基于JVM的語言(例如Scala)一起使用。 顧名思義,commons守護程序是Apache許可的。
Commons守護程序包括以下功能:
- 如果它消失了,將自動重新啟動JVM
- 使用標準OS機制啟用JVM進程的安全關閉(基于Tomcat TCP的關閉機制容易出錯且不安全)
- 重定向STDERR / STDOUT并設置JVM進程名稱
- 允許與OS初始化腳本機制集成(記錄JVM進程pid)
- 將JVM進程與父進程和控制臺分離
- 以減少的OS特權運行JVM和應用程序
- 允許與OS工具(例如logrotate)協調日志文件管理(使用SIGUSR1信號重新打開日志文件)
部署Commons守護程序
從應用程序開發人員的角度來看,commons守護程序由兩部分組成:用于啟動應用程序的jsvc二進制文件和commons守護程序Java API。 在啟動期間,jsvc二進制文件通過應用程序實現并由commons守護程序Java API定義的生命周期方法來引導應用程序。 Jsvc創建一個控制過程,以在異常終止時監視和重新啟動應用程序。 這是與應用程序一起部署commons守護程序的概述:
實踐經驗
Tomcat發行版包括“ daemon.sh”,這是一個通用包裝外殼腳本,可用作創建特定于系統的初始化腳本變體的基礎。 我遇到的問題之一是包裝腳本的調用者無法覆蓋wait配置參數的默認值。 在某些情況下,Tomcat隨機數生成器初始化可能會超過最大等待時間,從而導致初始化腳本報告失敗,即使最終啟動應用程序服務器也是如此。 現在似乎已解決此問題。
另一個問題是包裝器腳本不允許傳遞帶有空格的JVM參數。 例如,與JVM“ -XX:OnOutOfMemoryError”和co一起使用時,這可能很方便。 參數。 使用包裝腳本是可選的,也可以輕松更改,但是由于它包含一些有用的功能,因此我寧愿重用而不是復制它,因此我創建了一個功能請求并為此#55104提出了一個小補丁。
在找出正確的命令行參數以使jsvc引導您的應用程序時,“-debug”參數對于進行故障排除非常有用。 另外,默認情況下,jsvc將工作目錄更改為/,在這種情況下,絕對路徑通常應與其他選項一起使用。 “ -cwd”選項可用于覆蓋默認的工作目錄值。
守護碼頭
除Tomcat外,Jetty是我經常使用的另一個servlet容器。 由于集成已經存在,因此將common守護程序與Tomcat結合使用不會帶來任何挑戰,因此,我決定了解一下如何在不支持現成的common守護程序的應用服務器上工作。
為了在Jetty中實現必要的更改,我克隆了Jetty源代碼存儲庫,在Jetty bootstrap類中添加了jsvc生命周期方法,并構建了Jetty。 之后,我開始嘗試使用jsvc命令行參數來引導Jetty。 Jetty附帶了jetty.sh啟動腳本,該腳本具有稱為“ check”的選項,用于輸出與安裝相關的各種信息。 除其他外,它輸出將與JVM一起使用的命令行參數。 這為jsvc命令行提供了一個很好的起點。
這些是我最終得到的命令行:
export JH=$HOME/jetty-9.2.2-SNAPSHOT export JAVA_HOME=`/usr/libexec/java_home -v 1.8` jsvc -debug -pidfile $JH/jetty.pid -outfile $JH/std.out -errfile $JH/std.err -Djetty.logs=$JH/logs -Djetty.home=$JH -Djetty.base=$JH -Djava.io.tmpdir=/var/folders/g6/zmr61rsj11q5zjmgf96rhvy0sm047k/T/ -classpath $JH/commons-daemon-1.0.15.jar:$JH/start.jar org.eclipse.jetty.start.Main jetty.state=$JH/jetty.state jetty-logging.xml jetty-started.xml這可以用作適當的生產級初始化腳本的起點,以啟動和關閉Jetty。
我在Jetty項目問題跟蹤器中將我的代碼更改作為問題#439672提交,并且剛剛得知更改已與上游代碼庫合并,因此您將來應該可以使用Apache commons守護程序jsvc來守護Jetty。盒子。
翻譯自: https://www.javacodegeeks.com/2014/07/daemonizing-jvm-based-applications.html
總結
以上是生活随笔為你收集整理的守护基于JVM的应用程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vtm机是什么?
- 下一篇: 编译时检查JPA查询