最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot實現(xiàn)應(yīng)用開機自啟動與進程守護配置方案

 更新時間:2025年07月11日 09:24:18   作者:風象南  
機房意外斷電,恢復(fù)供電后所有服務(wù)器重啟,但SpringBoot應(yīng)用沒有自動啟動,事后排查發(fā)現(xiàn),沒有留下開機自啟動配置文檔,所以本文整理了兩套SpringBoot應(yīng)用開機自啟動與進程守護方案,需要的朋友可以參考下

一個故(shi)事(gu)

"小王,生產(chǎn)環(huán)境怎么回事?服務(wù)全掛了!"

上個月一個周六的凌晨,小王被這通電話驚醒。

機房意外斷電,恢復(fù)供電后所有服務(wù)器重啟,但我們的SpringBoot應(yīng)用沒有自動啟動,導(dǎo)致業(yè)務(wù)中斷了整整40分鐘。

事后排查發(fā)現(xiàn),是之前的運維同事離職時沒有留下開機自啟動配置文檔。更糟的是,應(yīng)用運行中偶爾會因為OOM崩潰,也沒有任何進程守護機制。

經(jīng)歷這次事故后,小王整理了兩套SpringBoot應(yīng)用開機自啟動與進程守護方案,在生產(chǎn)環(huán)境穩(wěn)定運行至今。

方案一:systemd配置(推薦)

什么是systemd?

簡單說,systemd是現(xiàn)在Linux系統(tǒng)的"大管家",負責管理系統(tǒng)啟動和服務(wù)進程。

幾乎所有主流Linux(CentOS 、Ubuntu 、Debian等)都支持使用systemd。

為什么推薦它?因為:

原生集成:不需要額外安裝軟件 功能強大:支持開機自啟、進程監(jiān)控、日志管理 配置簡單:一個服務(wù)文件搞定所有設(shè)置

實戰(zhàn)步驟:從0到1配置

1. 準備SpringBoot應(yīng)用

假設(shè)我們的應(yīng)用信息:

  • 應(yīng)用名稱:demo-app
  • JAR文件路徑:/opt/apps/demo-app.jar
  • 運行用戶:appuser(建議使用非root用戶)
  • 日志路徑:/var/log/demo-app.log

2. 創(chuàng)建啟動腳本(關(guān)鍵)

不要直接在systemd中調(diào)用java命令!創(chuàng)建一個啟動腳本/opt/apps/start.sh

#!/bin/bash
# SpringBoot應(yīng)用啟動腳本
APP_NAME="demo-app"
JAR_FILE="/opt/apps/demo-app.jar"
LOG_FILE="/var/log/${APP_NAME}.log"
JVM_OPTS="-Xms512m -Xmx512m -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
SERVER_PORT=8080

# 檢查JAR文件是否存在
if [ ! -f "$JAR_FILE" ]; then
    echo "錯誤:JAR文件 $JAR_FILE 不存在!"
    exit 1
fi

# 檢查端口是否被占用
check_port() {
    netstat -tlnp | grep ":$SERVER_PORT " > /dev/null
    return $?
}

if check_port; then
    echo "錯誤:端口 $SERVER_PORT 已被占用!"
    netstat -tlnp | grep ":$SERVER_PORT "
    exit 1
fi

# 啟動應(yīng)用
echo "開始啟動 $APP_NAME ..."
nohup java $JVM_OPTS -jar $JAR_FILE --server.port=$SERVER_PORT > $LOG_FILE 2>&1 &

# 等待應(yīng)用啟動
echo "等待應(yīng)用啟動,端口:$SERVER_PORT ..."
for i in {1..30}; do
    if check_port; then
        echo "$APP_NAME 啟動成功!"
        echo "日志文件:$LOG_FILE"
        exit 0
    fi
    sleep 1
done

# 啟動超時處理
echo "錯誤:$APP_NAME 啟動超時!"
echo "查看日志獲取詳細信息:tail -f $LOG_FILE"
exit 1

給腳本添加執(zhí)行權(quán)限:

chmod +x /opt/apps/start.sh

3. 創(chuàng)建systemd服務(wù)文件

創(chuàng)建/etc/systemd/system/demo-app.service

[Unit]
Description=Demo SpringBoot Application
Documentation=https://example.com/docs
After=network.target mysql.service  # 依賴網(wǎng)絡(luò)和MySQL服務(wù)啟動后再啟動
Wants=mysql.service  # MySQL啟動失敗不影響本服務(wù)啟動

[Service]
User=appuser
Group=appuser
WorkingDirectory=/opt/apps
ExecStart=/opt/apps/start.sh
# 自定義停止命令(優(yōu)雅關(guān)閉)
ExecStop=/bin/bash -c "PID=$(pgrep -f 'demo-app.jar'); if [ -n "$PID" ]; then kill -15 $PID; sleep 10; if ps -p $PID > /dev/null; then kill -9 $PID; fi; fi"
# 啟動前備份日志
ExecStartPre=/bin/bash -c "if [ -f /var/log/demo-app.log ]; then mv /var/log/demo-app.log /var/log/demo-app.log.$(date +%%Y%%m%%d%%H%%M%%S); fi"
SuccessExitStatus=143  # 識別SpringBoot優(yōu)雅關(guān)閉狀態(tài)碼
Restart=always  # 總是重啟(異常退出時)
RestartSec=5  # 重啟間隔5秒
TimeoutStartSec=300  # 啟動超時時間(5分鐘)
TimeoutStopSec=60  # 停止超時時間
Environment="SPRING_PROFILES_ACTIVE=prod"  # 環(huán)境變量
Environment="JAVA_HOME=/usr/lib/jvm/java-11-openjdk"

[Install]
WantedBy=multi-user.target  # 多用戶模式下啟動

4. 服務(wù)管理命令

# 重載systemd配置(修改服務(wù)文件后必須執(zhí)行)
sudo systemctl daemon-reload

# 啟動服務(wù)
sudo systemctl start demo-app

# 停止服務(wù)
sudo systemctl stop demo-app

# 重啟服務(wù)
sudo systemctl restart demo-app

# 設(shè)置開機自啟
sudo systemctl enable demo-app

# 取消開機自啟
sudo systemctl disable demo-app

# 查看服務(wù)狀態(tài)
sudo systemctl status demo-app

# 查看服務(wù)日志
sudo journalctl -u demo-app -f  # -f表示實時跟蹤

狀態(tài)檢查示例

 demo-app.service - Demo SpringBoot Application
   Loaded: loaded (/etc/systemd/system/demo-app.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2023-11-15 10:30:00 CST; 5min ago
     Docs: https://example.com/docs
  Process: 1234 ExecStartPre=/bin/bash -c if [ -f /var/log/demo-app.log ]; then mv /var/log/demo-app.log /var/log/demo-app.log.20231115102959; fi (code=exited, status=0/SUCCESS)
 Main PID: 1245 (start.sh)
    Tasks: 30 (limit: 4915)
   Memory: 256.0M
   CGroup: /system.slice/demo-app.service
           ├─1245 /bin/bash /opt/apps/start.sh
           └─1250 java -Xms512m -Xmx512m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar /opt/apps/demo-app.jar --server.port=8080

避坑指南

坑1:權(quán)限問題導(dǎo)致啟動失敗

現(xiàn)象Job for demo-app.service failed because the control process exited with error code.
解決:確保appuser用戶有JAR文件和日志目錄的權(quán)限

sudo chown -R appuser:appuser /opt/apps /var/log/demo-app.log

坑2:應(yīng)用啟動慢導(dǎo)致超時

現(xiàn)象Failed to start Demo SpringBoot Application. Timeout was reached.
解決:增加啟動超時時間

[Service]
TimeoutStartSec=300  # 5分鐘

坑3:優(yōu)雅關(guān)閉不生效

現(xiàn)象:執(zhí)行stop后應(yīng)用立即退出,@PreDestroy方法未執(zhí)行
解決:配置優(yōu)雅關(guān)閉參數(shù)

[Service]
KillSignal=SIGTERM
TimeoutStopSec=60

同時在SpringBoot配置文件中添加:

server:
  shutdown: graceful
spring:
  lifecycle:
    timeout-per-shutdown-phase: 30s

方案二:Supervisor配置(兼容更多系統(tǒng))

如果你的服務(wù)器是較老的Linux發(fā)行版(如CentOS 6),或者需要管理多個進程,Supervisor是個不錯的選擇。

它是Python編寫的進程管理工具,跨平臺性好。

安裝Supervisor

CentOS安裝

# 安裝EPEL源
sudo yum install -y epel-release
# 安裝Supervisor
sudo yum install -y supervisor
# 啟動并設(shè)置開機自啟
sudo systemctl start supervisord
sudo systemctl enable supervisord

Ubuntu安裝

sudo apt-get update
sudo apt-get install -y supervisor

創(chuàng)建應(yīng)用配置文件

創(chuàng)建/etc/supervisord.d/demo-app.ini

[program:demo-app]
command=/usr/bin/java -Xms512m -Xmx512m -XX:+UseG1GC -jar /opt/apps/demo-app.jar --server.port=8080
directory=/opt/apps
user=appuser
autostart=true  # 隨Supervisor啟動而啟動
autorestart=true  # 進程退出時自動重啟
startretries=3  # 啟動失敗重試次數(shù)
startsecs=10  # 啟動后穩(wěn)定運行10秒才算成功
redirect_stderr=true  # 錯誤日志重定向到標準輸出
stdout_logfile=/var/log/demo-app.log
stdout_logfile_maxbytes=10MB  # 日志文件大小限制
stdout_logfile_backups=10  # 日志備份數(shù)量
environment=
    SPRING_PROFILES_ACTIVE="prod",
    JAVA_HOME="/usr/lib/jvm/java-11-openjdk"

Supervisor管理命令

# 重載配置(修改配置后執(zhí)行)
sudo supervisorctl update

# 查看所有進程狀態(tài)
sudo supervisorctl status

# 啟動應(yīng)用
sudo supervisorctl start demo-app

# 停止應(yīng)用
sudo supervisorctl stop demo-app

# 重啟應(yīng)用
sudo supervisorctl restart demo-app

# 查看應(yīng)用日志
sudo supervisorctl tail -f demo-app

實戰(zhàn)經(jīng)驗: "Supervisor的日志輪轉(zhuǎn)功能非常實用,但要注意單位是MB不是GB!另外,它本身也需要通過systemd來管理開機啟動,有點套娃的感覺。"

兩種方案對比與選擇建議

特性systemdSupervisor
系統(tǒng)集成原生集成,無需額外安裝需要單獨安裝
配置復(fù)雜度中等簡單
進程監(jiān)控支持支持
多應(yīng)用管理配置文件分散集中管理
跨平臺性僅LinuxLinux/Unix/Mac

使用建議

生產(chǎn)環(huán)境首選systemd:原生、輕量、功能足夠 多應(yīng)用管理選Supervisor:集中配置,適合管理多個微服務(wù) Docker環(huán)境不需要:容器本身提供進程管理

高級配置:健康檢查與自動恢復(fù)

systemd健康檢查

創(chuàng)建健康檢查腳本/opt/apps/healthcheck.sh

#!/bin/bash
PORT=8080
TIMEOUT=5

# 檢查健康端點
result=$(curl -s -w "%{http_code}" -o /dev/null --connect-timeout $TIMEOUT http://localhost:$PORT/actuator/health)

if [ "$result" -eq 200 ]; then
    exit 0
else
    echo "健康檢查失敗,HTTP狀態(tài)碼: $result"
    exit 1
fi

修改服務(wù)文件添加健康檢查

[Service]
HealthCheckSec=30  # 每30秒檢查一次
HealthCheckCmd=/opt/apps/healthcheck.sh
HealthCheckFailureAction=restart  # 檢查失敗則重啟

SpringBoot需暴露健康端點

management:
  endpoints:
    web:
      exposure:
        include: health
  endpoint:
    health:
      show-details: always
      probes:
        enabled: true

"健康檢查是防止'僵尸進程'的有效手段。我們可能會遇到應(yīng)用進程存在但無法提供服務(wù)的情況,有了健康檢查后,systemd會自動重啟這類異常應(yīng)用。"

防止無限重啟策略

無論是systemd還是Supervisor,都需要配置重啟限制,避免應(yīng)用陷入重啟循環(huán):

systemd配置

[Unit]
StartLimitInterval=600  # 10分鐘內(nèi)
StartLimitBurst=5  # 最多重啟5次
StartLimitAction=poweroff  # 達到限制后關(guān)閉系統(tǒng)(極端情況)

Supervisor配置

[program:demo-app]
autorestart=unexpected  # 僅意外退出時重啟
exitcodes=0,143  # 正常退出狀態(tài)碼

總結(jié)

按照這些步驟配置后,你的SpringBoot應(yīng)用將具備服務(wù)器重啟或應(yīng)用異常down掉后自動恢復(fù)的能力。

以上就是SpringBoot實現(xiàn)應(yīng)用開機自啟動與進程守護配置方案的詳細內(nèi)容,更多關(guān)于SpringBoot應(yīng)用開機自啟動與進程守護的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java中springboot搭建html的操作代碼

    Java中springboot搭建html的操作代碼

    這篇文章主要介紹了Java中springboot搭建html的相關(guān)操作,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-08-08
  • Java編程接口詳細

    Java編程接口詳細

    這篇文章主要小編主要給大家講解的是Java編程中的接口,文章會從抽象類和抽象方法開始展開內(nèi)容,感興趣的小伙伴可以參考下面文章的具體內(nèi)容
    2021-10-10
  • java對象克隆實現(xiàn)方法詳解

    java對象克隆實現(xiàn)方法詳解

    這篇文章主要給大家介紹了關(guān)于java對象克隆實現(xiàn)的相關(guān)資料,克隆就是復(fù)制一個對象的副本,Java支持我們對一個對象進行克隆,通常用在裝飾模式和原型模式中,需要的朋友可以參考下
    2023-06-06
  • JavaWeb項目部署到服務(wù)器詳細步驟詳解

    JavaWeb項目部署到服務(wù)器詳細步驟詳解

    這篇文章主要介紹了JavaWeb項目如何部署到服務(wù)器,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧
    2019-04-04
  • SpringMVC后端返回數(shù)據(jù)到前端代碼示例

    SpringMVC后端返回數(shù)據(jù)到前端代碼示例

    這篇文章主要介紹了SpringMVC后端返回數(shù)據(jù)到前端代碼示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友可以參考下
    2020-04-04
  • 創(chuàng)建一個IDEA的Java項目實現(xiàn)方式

    創(chuàng)建一個IDEA的Java項目實現(xiàn)方式

    本文介紹了創(chuàng)建Java項目的步驟,首先,點擊NewProject和EmptyProject并選擇Next,然后修改項目名,新建模塊和包,接著,在src右鍵點擊New新建JAVA類,最后點擊回車鍵即可創(chuàng)建成功,本文為個人經(jīng)驗總結(jié)
    2026-05-05
  • java web實現(xiàn)郵箱激活與忘記密碼

    java web實現(xiàn)郵箱激活與忘記密碼

    這篇文章主要為大家詳細介紹了java web實現(xiàn)郵箱激活與忘記密碼、重置密碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • SpringBoot使用Redis實現(xiàn)分布式緩存

    SpringBoot使用Redis實現(xiàn)分布式緩存

    這篇文章主要介紹了SpringBoot redis分布式緩存實現(xiàn)過程解析,文中通過示例代碼解析的非常詳細,感興趣的同學(xué)可以參考閱讀
    2023-04-04
  • java實現(xiàn)截取PDF指定頁并進行圖片格式轉(zhuǎn)換功能

    java實現(xiàn)截取PDF指定頁并進行圖片格式轉(zhuǎn)換功能

    這篇文章主要介紹了java實現(xiàn)截取PDF指定頁并進行圖片格式轉(zhuǎn)換功能,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-09-09
  • Java高效實現(xiàn)合并多個Word文檔的實戰(zhàn)指南

    Java高效實現(xiàn)合并多個Word文檔的實戰(zhàn)指南

    在企業(yè)開發(fā)和日常辦公自動化中,我們經(jīng)常需要處理 Word 文檔,本文將系統(tǒng)講解在 Java 中合并 Word 文檔的常用方法,提供完整示例,幫助你快速掌握文檔合并技巧
    2026-01-01

最新評論

鄂尔多斯市| 永年县| 藁城市| 蒙自县| 永和县| 定兴县| 墨竹工卡县| 宣武区| 石棉县| 岫岩| 乌兰察布市| 无为县| 广饶县| 南康市| 绍兴县| 宁化县| 贞丰县| 镇江市| 南京市| 胶南市| 兰坪| 阳山县| 依兰县| 诸暨市| 灵石县| 长子县| 高青县| 靖州| 潮州市| 互助| 弥渡县| 丹棱县| 安义县| 启东市| 玛曲县| 岳阳市| 阿拉善左旗| 唐山市| 南充市| 汉源县| 上思县|