
我正在嘗試在 Ubuntu 18.04 上配置 spring-boot 應用程式(由其他人開發 - 我不是 java 程式設計師)。開發人員之前添加了符號連結來/etc/init.d
啟用該服務 - 它在啟動時啟動良好。但是,如果該服務隨後失敗,systemd 仍會報告它正在運行:
[email protected]:/var/log/apps# systemctl status crm-service
● crm-service.service - LSB: crm-service
Loaded: loaded (/etc/init.d/crm-service; generated)
Active: active (exited) since Wed 2020-04-15 12:27:15 BST; 3h 56min ago
Docs: man:systemd-sysv-generator(8)
Process: 8656 ExecStop=/etc/init.d/crm-service stop (code=exited, status=0/SUCCESS)
Process: 8703 ExecStart=/etc/init.d/crm-service start (code=exited, status=0/SUCCESS)
Apr 15 12:27:15 example.com systemd[1]: Starting LSB: crm-service...
Apr 15 12:27:15 example.com crm-service[8703]: /var/services/crm-service.conf: line 1: -Xms96M: command not found
Apr 15 12:27:15 example.com crm-service[8703]: Started [8747]
Apr 15 12:27:15 example.com systemd[1]: Started LSB: crm-service.
當我看到相同的 systemd 單元文件對於互聯網上發布的 springboot,我沒有看到任何可能解決此問題的內容。
- 如何讓 systemd 查看服務的真實狀態? (它將打開一個偵聽套接字,但在隨機的高連接埠上)
- 有沒有辦法讓 systemd 試試看輕輕地重新啟動它知道失敗的服務?
答案1
Systemd 有很多批評者,其中很多都還不錯,但事實並非如此。Systemd 可以追蹤從啟動腳本分叉(或克隆)的所有進程和線程,如果沒有留下任何進程和線程,則認為服務已死亡。
我看到的第一個問題是:systemd 不使用啟動/停止腳本/etc/init.d
,它只是一個相容性插件。相反,systemd 使用單元文件,即其所有服務的設定檔。
systemd sysv init compat 模組有效地為/etc/init.d
.這並不總是可以的,因為初始化腳本缺少所需的資訊(或不可能從它們中提取資訊)。
該 compat 模組的工作方式是,如果退出程式碼非零,則 systemd 認為 init 腳本失敗,因此服務無法運作。零退出代碼意味著成功執行。如果 init 腳本有錯誤並且即使失敗也給出零退出代碼,它會欺騙 systemd。
初始化腳本錯誤最可能的原因是它在背景啟動進程,然後總是以零退出。我對大多數由自訂提供者編寫的初始化腳本的共同經驗是……也許它們中的大多數都有很大的改進空間。不要相信他們,看看他們做了什麼並修復它們。對於你的情況,最好是檢查一下,
- 它如何啟動你的java應用程式
- 從哪裡開始
- 由哪個使用者啟動
並使用單元文件重現相同的功能。
無法從 systemd 自動重新啟動 initscripts,但可以從單元檔案自動重新啟動。
請注意,如果 Java 程式隨機崩潰,這也是一個嚴重的問題。所有健全的 java 框架都會正確處理自己的致命錯誤(它們捕獲所有異常,記錄並繼續)。
init 腳本中另一個很可能的錯誤是它找不到您的 JVM(最有可能是:/usr/bin/java),因此它用空字串取代它,導致它嘗試將 JVM 標誌作為 shell 命令啟動。顯然-Xms96M
您的系統中沒有命令,但/usr/bin/java -Xms96M ...
可以使用。
Spring Boot 應用程式的範例單元檔案:
[Unit]
Description=Crm Spring Boot App Example
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/java -Xms96M ...other flags... your.spring.boot.jar
User=exampleuser
Group=examplegroup
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=exampleapp
WorkingDirectory=/path/to/app/home
[Install]
WantedBy=multi-user.target
Alias=exampleapp.service
該單元檔案也將 Java 進程的標準輸出和錯誤重定向到系統日誌中。
若要自動重新啟動應用程序,請插入
RestartSec=5s
Restart=on-failure
進入該[Service]
部分。
有一個 systemd 教程GoLinuxCloud.com。