SpringBoot利用可視化服務(wù)管理腳本部署應(yīng)用
在SpringBoot應(yīng)用的生產(chǎn)環(huán)境部署中,傳統(tǒng)的手動啟停服務(wù)方式不僅效率低下,還容易出錯。
今天分享一個功能強大的可視化服務(wù)管理腳本,讓SpringBoot應(yīng)用的部署和運維變得簡單高效。
痛點分析:傳統(tǒng)部署方式的困擾
相信很多開發(fā)者都遇到過這些問題:
- 操作繁瑣:每次部署都要手動執(zhí)行一堆命令
- 狀態(tài)不明:不知道服務(wù)是否真正啟動成功
- 日志分散:查看日志需要記住各種路徑
- 回滾困難:出問題時手忙腳亂找備份
- 多服務(wù)管理:微服務(wù)架構(gòu)下管理復(fù)雜度倍增
這些問題不僅影響開發(fā)效率,還增加了生產(chǎn)環(huán)境的風(fēng)險。
解決方案:可視化服務(wù)管理器
為了解決這些痛點,我開發(fā)了一套完整的SpringBoot服務(wù)管理解決方案,核心特性包括:
可視化操作界面
告別枯燥的命令行操作,采用彩色終端界面:
#################### SpringBoot服務(wù)管理器 ####################
當前時間: 2024-01-15 14:30:25
配置文件: /path/to/services.conf
日志目錄: /path/to/logs
================== 服務(wù)列表 ==================
序號 服務(wù)名稱 端口 狀態(tài)
-----------------------------------------------
1 user-service 8080 運行中 (PID: 1234, Port: 8080)
2 order-service 8081 已停止
3 payment-service 8082 啟動中 (PID: 5678)
===============================================
界面直觀清晰,服務(wù)狀態(tài)一目了然,支持實時狀態(tài)更新和彩色狀態(tài)標識。
智能服務(wù)管理
1. 配置驅(qū)動的服務(wù)管理
通過簡單的配置文件管理所有服務(wù):
# services.conf 配置格式
# 服務(wù)名稱|JAR路徑|端口|環(huán)境|JVM參數(shù)
user-service|/opt/apps/user-service.jar|8080|prod|-Xms512m -Xmx1024m
order-service|/opt/apps/order-service.jar|8081|prod|-Xms256m -Xmx512m
這種配置方式的優(yōu)勢:
- 統(tǒng)一管理:所有服務(wù)配置集中管理
- 靈活配置:支持不同JVM參數(shù)和環(huán)境配置
- 易于維護:修改配置無需改動腳本
2. 智能啟停機制
優(yōu)雅啟動流程:
檢查JAR文件 → 驗證端口可用性 → 構(gòu)建啟動命令
→ 后臺啟動服務(wù) → 健康檢查 → 狀態(tài)確認
安全停止流程:
發(fā)送TERM信號 → 等待優(yōu)雅停止 → 超時強制終止 → 狀態(tài)確認
這種機制確保服務(wù)啟停的可靠性,避免了常見的端口占用和進程殘留問題。
全方位監(jiān)控功能
1. 實時狀態(tài)監(jiān)控
==================== 服務(wù)詳細信息 ====================
服務(wù)名稱: user-service
運行狀態(tài): 運行中 (PID: 1234, Port: 8080)
內(nèi)存使用: 345.6 MB
CPU使用: 12.5%
啟動時間: Dec 15 14:30
日志大小: 25.3M
======================================================
2. 系統(tǒng)資源監(jiān)控
==================== 系統(tǒng)資源信息 ====================
CPU使用率: 15.2%
內(nèi)存使用: 4.2G / 8.0G
磁盤使用: 25G / 50G (52%)
Java進程: 3個運行中
======================================================
這些監(jiān)控信息幫助運維人員及時發(fā)現(xiàn)性能瓶頸和資源問題。
智能日志管理
支持多種日志查看方式:
- 實時跟蹤:
tail -f
實時查看最新日志 - 歷史查看:查看指定行數(shù)的歷史日志
- 全文瀏覽:使用less命令瀏覽完整日志
- 日志輪轉(zhuǎn):自動管理日志文件大小
日志管理界面:
請選擇查看方式:
1) 查看最后50行
2) 查看最后100行
3) 實時跟蹤日志
4) 查看全部日志
批量操作支持
微服務(wù)架構(gòu)下,批量操作必不可少:
==================== 批量操作菜單 ====================
1) 啟動所有服務(wù)
2) 停止所有服務(wù)
3) 重啟所有服務(wù)
4) 查看所有服務(wù)狀態(tài)
======================================================
批量操作特別適用于: 系統(tǒng)重啟后的服務(wù)恢復(fù) 版本發(fā)布時的服務(wù)更新 故障處理時的快速響應(yīng)
自動化部署解決方案
除了服務(wù)管理,還提供了完整的自動化部署腳本:
一鍵部署流程
./deploy.sh deploy app-1.0.0.jar
部署流程包括:
1. 環(huán)境檢查:驗證部署環(huán)境和依賴
2. 版本備份:自動備份當前運行版本
3. 服務(wù)停止:優(yōu)雅停止當前服務(wù)
4. 文件部署:復(fù)制新版本到部署目錄
5. 服務(wù)啟動:啟動新版本服務(wù)
6. 健康檢查:驗證服務(wù)是否正常運行
7. 清理備份:保留最近5個版本備份
安全回滾機制
當部署出現(xiàn)問題時:
./deploy.sh rollback
回滾流程:
- 自動查找最新備份版本
- 停止問題版本服務(wù)
- 恢復(fù)備份文件
- 重啟服務(wù)并驗證
這種設(shè)計確保了部署過程的安全性,即使出現(xiàn)問題也能快速恢復(fù)。
實戰(zhàn)應(yīng)用場景
場景1:微服務(wù)集群管理
某電商公司有用戶服務(wù)、訂單服務(wù)、支付服務(wù)等10個微服務(wù):
傳統(tǒng)方式:
- 需要登錄到每臺服務(wù)器
- 手動執(zhí)行啟停命令
- 分別查看各服務(wù)日志
- 耗時30分鐘+
使用腳本后:
- 一個界面管理所有服務(wù)
- 批量操作3分鐘完成
- 狀態(tài)監(jiān)控一目了然
- 效率提升10倍
場景2:版本發(fā)布管理
發(fā)布前:
# 查看當前所有服務(wù)狀態(tài) 選擇批量操作 → 查看所有服務(wù)狀態(tài)
發(fā)布過程:
# 逐個服務(wù)更新 ./deploy.sh deploy user-service-v2.0.jar ./deploy.sh deploy order-service-v2.0.jar
發(fā)布驗證:
# 健康檢查和監(jiān)控 ./deploy.sh health
場景3:故障應(yīng)急處理
當生產(chǎn)環(huán)境出現(xiàn)問題:
1. 快速定位:通過狀態(tài)監(jiān)控快速識別問題服務(wù)
2. 日志分析:實時查看相關(guān)服務(wù)日志
3. 緊急處理:重啟問題服務(wù)或快速回滾
4. 影響評估:查看系統(tǒng)資源使用情況
最佳實踐建議
1. 配置管理
使用版本控制管理配置文件
不同環(huán)境使用不同的配置
定期備份配置文件
2. 監(jiān)控告警
配合監(jiān)控系統(tǒng)使用
設(shè)置關(guān)鍵指標告警
建立故障處理流程
3. 安全考慮
限制腳本執(zhí)行權(quán)限
使用非root用戶運行
定期清理敏感日志
4. 性能優(yōu)化
合理配置JVM參數(shù)
監(jiān)控服務(wù)資源使用
定期優(yōu)化配置參數(shù)
總結(jié)
這套基于SHELL的SpringBoot服務(wù)管理解決方案通過可視化界面、智能管理機制、資源監(jiān)控和自動化部署,可以極大提供服務(wù)管理效率。
它不僅大大提升了運維效率,還降低了操作風(fēng)險,特別適合單機多服務(wù)和小規(guī)模微服務(wù)架構(gòu)的部署場景。
如果你也在為SpringBoot應(yīng)用的部署和管理而煩惱,不妨試試這套解決方案。相信它會讓你的運維工作變得更加輕松高效!
腳本附錄
springboot-service-manager
#!/bin/bash # SpringBoot服務(wù)管理腳本 - 可視化版本 # 支持多個服務(wù)的啟動、停止、重啟、狀態(tài)查看等功能 # 配置目錄 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" CONFIG_FILE="$SCRIPT_DIR/services.conf" LOG_DIR="$SCRIPT_DIR/logs" # 創(chuàng)建必要目錄 mkdir -p "$LOG_DIR" # 顏色定義 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' PURPLE='\033[0;35m' CYAN='\033[0;36m' WHITE='\033[1;37m' NC='\033[0m' # No Color # 加載服務(wù)配置 load_services() { if [[ ! -f "$CONFIG_FILE" ]]; then echo -e "${RED}配置文件不存在: $CONFIG_FILE${NC}" echo "請先創(chuàng)建配置文件,參考 services.conf.example" exit 1 fi # 清空服務(wù)數(shù)組 unset SERVICE_NAMES unset SERVICE_PATHS unset SERVICE_PORTS unset SERVICE_PROFILES unset SERVICE_JVM_OPTS declare -g -a SERVICE_NAMES=() declare -g -a SERVICE_PATHS=() declare -g -a SERVICE_PORTS=() declare -g -a SERVICE_PROFILES=() declare -g -a SERVICE_JVM_OPTS=() # 讀取配置文件 while IFS='|' read -r name path port profile jvm_opts; do # 跳過注釋和空行 [[ $name =~ ^#.*$ ]] && continue [[ -z "$name" ]] && continue SERVICE_NAMES+=("$name") SERVICE_PATHS+=("$path") SERVICE_PORTS+=("$port") SERVICE_PROFILES+=("$profile") SERVICE_JVM_OPTS+=("$jvm_opts") done < "$CONFIG_FILE" } # 獲取服務(wù)PID get_service_pid() { local service_name=$1 local port=$2 # 先通過端口查找 if [[ -n "$port" ]]; then pid=$(lsof -ti:$port 2>/dev/null) if [[ -n "$pid" ]]; then echo $pid return fi fi # 通過jar文件名查找 pid=$(ps aux | grep java | grep -v grep | grep "$service_name" | awk '{print $2}') echo $pid } # 檢查服務(wù)狀態(tài) check_service_status() { local index=$1 local service_name=${SERVICE_NAMES[$index]} local port=${SERVICE_PORTS[$index]} local pid=$(get_service_pid "$service_name" "$port") if [[ -n "$pid" ]]; then # 檢查端口是否可訪問 if [[ -n "$port" ]] && nc -z localhost $port 2>/dev/null; then echo -e "${GREEN}運行中${NC} (PID: $pid, Port: $port)" else echo -e "${YELLOW}啟動中${NC} (PID: $pid)" fi return 0 else echo -e "${RED}已停止${NC}" return 1 fi } # 啟動服務(wù) start_service() { local index=$1 local service_name=${SERVICE_NAMES[$index]} local jar_path=${SERVICE_PATHS[$index]} local port=${SERVICE_PORTS[$index]} local profile=${SERVICE_PROFILES[$index]} local jvm_opts=${SERVICE_JVM_OPTS[$index]} echo -e "${BLUE}正在啟動服務(wù): $service_name${NC}" # 檢查jar文件是否存在 if [[ ! -f "$jar_path" ]]; then echo -e "${RED}錯誤: JAR文件不存在 - $jar_path${NC}" return 1 fi # 檢查服務(wù)是否已經(jīng)運行 local pid=$(get_service_pid "$service_name" "$port") if [[ -n "$pid" ]]; then echo -e "${YELLOW}服務(wù)已經(jīng)在運行中 (PID: $pid)${NC}" return 0 fi # 構(gòu)建啟動命令 local cmd="java" [[ -n "$jvm_opts" ]] && cmd="$cmd $jvm_opts" [[ -n "$profile" ]] && cmd="$cmd -Dspring.profiles.active=$profile" cmd="$cmd -jar $jar_path" # 啟動服務(wù) local log_file="$LOG_DIR/${service_name}.log" nohup $cmd > "$log_file" 2>&1 & local new_pid=$! echo "啟動命令: $cmd" >> "$log_file" echo "啟動時間: $(date)" >> "$log_file" echo "進程PID: $new_pid" >> "$log_file" echo "----------------------------------------" >> "$log_file" # 等待服務(wù)啟動 echo -n "等待服務(wù)啟動" for i in {1..30}; do sleep 1 echo -n "." if [[ -n "$port" ]] && nc -z localhost $port 2>/dev/null; then echo echo -e "${GREEN}服務(wù)啟動成功!${NC} (PID: $new_pid, Port: $port)" return 0 fi done echo echo -e "${YELLOW}服務(wù)已啟動,但端口檢查超時${NC} (PID: $new_pid)" echo "請查看日志文件: $log_file" return 0 } # 停止服務(wù) stop_service() { local index=$1 local service_name=${SERVICE_NAMES[$index]} local port=${SERVICE_PORTS[$index]} echo -e "${BLUE}正在停止服務(wù): $service_name${NC}" local pid=$(get_service_pid "$service_name" "$port") if [[ -z "$pid" ]]; then echo -e "${YELLOW}服務(wù)未運行${NC}" return 0 fi # 優(yōu)雅停止 echo "發(fā)送TERM信號..." kill -TERM $pid # 等待服務(wù)停止 echo -n "等待服務(wù)停止" for i in {1..15}; do sleep 1 echo -n "." if ! kill -0 $pid 2>/dev/null; then echo echo -e "${GREEN}服務(wù)已停止${NC}" return 0 fi done # 強制停止 echo echo "優(yōu)雅停止超時,強制停止..." kill -KILL $pid 2>/dev/null sleep 2 if ! kill -0 $pid 2>/dev/null; then echo -e "${GREEN}服務(wù)已強制停止${NC}" return 0 else echo -e "${RED}服務(wù)停止失敗${NC}" return 1 fi } # 重啟服務(wù) restart_service() { local index=$1 local service_name=${SERVICE_NAMES[$index]} echo -e "${BLUE}正在重啟服務(wù): $service_name${NC}" stop_service $index sleep 2 start_service $index } # 查看服務(wù)日志 view_service_log() { local index=$1 local service_name=${SERVICE_NAMES[$index]} local log_file="$LOG_DIR/${service_name}.log" if [[ ! -f "$log_file" ]]; then echo -e "${RED}日志文件不存在: $log_file${NC}" return 1 fi echo -e "${BLUE}查看服務(wù)日志: $service_name${NC}" echo "日志文件: $log_file" echo "----------------------------------------" # 選擇查看方式 echo "請選擇查看方式:" echo "1) 查看最后50行" echo "2) 查看最后100行" echo "3) 實時跟蹤日志" echo "4) 查看全部日志" echo "0) 返回主菜單" read -p "請輸入選擇 [1-4]: " log_choice case $log_choice in 1) tail -50 "$log_file" ;; 2) tail -100 "$log_file" ;; 3) echo "按 Ctrl+C 退出實時跟蹤" sleep 2 tail -f "$log_file" ;; 4) less "$log_file" ;; 0) return ;; *) echo -e "${RED}無效選擇${NC}" ;; esac } # 顯示服務(wù)詳細信息 show_service_detail() { local index=$1 local service_name=${SERVICE_NAMES[$index]} local jar_path=${SERVICE_PATHS[$index]} local port=${SERVICE_PORTS[$index]} local profile=${SERVICE_PROFILES[$index]} local jvm_opts=${SERVICE_JVM_OPTS[$index]} clear echo -e "${CYAN}==================== 服務(wù)詳細信息 ====================${NC}" echo -e "${WHITE}服務(wù)名稱:${NC} $service_name" echo -e "${WHITE}JAR路徑:${NC} $jar_path" echo -e "${WHITE}端口號:${NC} ${port:-未配置}" echo -e "${WHITE}環(huán)境配置:${NC} ${profile:-默認}" echo -e "${WHITE}JVM參數(shù):${NC} ${jvm_opts:-默認}" local pid=$(get_service_pid "$service_name" "$port") echo -e "${WHITE}運行狀態(tài):${NC} $(check_service_status $index)" if [[ -n "$pid" ]]; then echo -e "${WHITE}進程PID:${NC} $pid" echo -e "${WHITE}內(nèi)存使用:${NC} $(ps -p $pid -o rss= | awk '{printf "%.1f MB", $1/1024}')" echo -e "${WHITE}CPU使用:${NC} $(ps -p $pid -o %cpu= | awk '{print $1"%"}')" echo -e "${WHITE}啟動時間:${NC} $(ps -p $pid -o lstart= | awk '{print $1" "$2" "$3" "$4}')" fi local log_file="$LOG_DIR/${service_name}.log" if [[ -f "$log_file" ]]; then echo -e "${WHITE}日志文件:${NC} $log_file" echo -e "${WHITE}日志大小:${NC} $(du -h "$log_file" | awk '{print $1}')" fi echo -e "${CYAN}======================================================${NC}" echo read -p "按回車鍵返回主菜單..." } # 顯示系統(tǒng)資源使用情況 show_system_info() { clear echo -e "${CYAN}==================== 系統(tǒng)資源信息 ====================${NC}" # CPU使用率 cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | sed 's/%us,//') echo -e "${WHITE}CPU使用率:${NC} ${cpu_usage}%" # 內(nèi)存使用情況 memory_info=$(free -h | grep Mem) total_mem=$(echo $memory_info | awk '{print $2}') used_mem=$(echo $memory_info | awk '{print $3}') echo -e "${WHITE}內(nèi)存使用:${NC} $used_mem / $total_mem" # 磁盤使用情況 echo -e "${WHITE}磁盤使用:${NC}" df -h | grep -E '^/dev/' | awk '{printf " %s: %s / %s (%s)\n", $1, $3, $2, $5}' # Java進程信息 echo -e "${WHITE}Java進程:${NC}" ps aux | grep java | grep -v grep | while read line; do pid=$(echo $line | awk '{print $2}') mem=$(echo $line | awk '{print $4}') cmd=$(echo $line | awk '{for(i=11;i<=NF;i++) printf "%s ", $i; print ""}') echo " PID: $pid, MEM: ${mem}%, CMD: ${cmd:0:50}..." done echo -e "${CYAN}======================================================${NC}" echo read -p "按回車鍵返回主菜單..." } # 批量操作菜單 batch_operations_menu() { while true; do clear echo -e "${PURPLE}==================== 批量操作菜單 ====================${NC}" echo "1) 啟動所有服務(wù)" echo "2) 停止所有服務(wù)" echo "3) 重啟所有服務(wù)" echo "4) 查看所有服務(wù)狀態(tài)" echo "0) 返回主菜單" echo -e "${PURPLE}======================================================${NC}" read -p "請輸入選擇 [0-4]: " batch_choice case $batch_choice in 1) echo -e "${BLUE}正在啟動所有服務(wù)...${NC}" for ((i=0; i<${#SERVICE_NAMES[@]}; i++)); do start_service $i echo done read -p "按回車鍵繼續(xù)..." ;; 2) echo -e "${BLUE}正在停止所有服務(wù)...${NC}" for ((i=0; i<${#SERVICE_NAMES[@]}; i++)); do stop_service $i echo done read -p "按回車鍵繼續(xù)..." ;; 3) echo -e "${BLUE}正在重啟所有服務(wù)...${NC}" for ((i=0; i<${#SERVICE_NAMES[@]}; i++)); do restart_service $i echo done read -p "按回車鍵繼續(xù)..." ;; 4) clear echo -e "${CYAN}==================== 所有服務(wù)狀態(tài) ====================${NC}" printf "%-20s %-10s %-15s\n" "服務(wù)名稱" "端口" "狀態(tài)" echo "------------------------------------------------------" for ((i=0; i<${#SERVICE_NAMES[@]}; i++)); do status=$(check_service_status $i) printf "%-20s %-10s %s\n" "${SERVICE_NAMES[$i]}" "${SERVICE_PORTS[$i]}" "$status" done echo -e "${CYAN}======================================================${NC}" read -p "按回車鍵繼續(xù)..." ;; 0) break ;; *) echo -e "${RED}無效選擇,請重新輸入${NC}" sleep 1 ;; esac done } # 服務(wù)管理菜單 service_management_menu() { local index=$1 local service_name=${SERVICE_NAMES[$index]} while true; do clear echo -e "${CYAN}==================== 服務(wù)管理: $service_name ====================${NC}" echo -e "當前狀態(tài): $(check_service_status $index)" echo echo "1) 啟動服務(wù)" echo "2) 停止服務(wù)" echo "3) 重啟服務(wù)" echo "4) 查看日志" echo "5) 服務(wù)詳情" echo "0) 返回主菜單" echo -e "${CYAN}================================================================${NC}" read -p "請輸入選擇 [0-5]: " service_choice case $service_choice in 1) start_service $index read -p "按回車鍵繼續(xù)..." ;; 2) stop_service $index read -p "按回車鍵繼續(xù)..." ;; 3) restart_service $index read -p "按回車鍵繼續(xù)..." ;; 4) view_service_log $index ;; 5) show_service_detail $index ;; 0) break ;; *) echo -e "${RED}無效選擇,請重新輸入${NC}" sleep 1 ;; esac done } # 主菜單 main_menu() { while true; do clear echo -e "${GREEN}#################### SpringBoot服務(wù)管理器 ####################${NC}" echo -e "${WHITE}當前時間: $(date '+%Y-%m-%d %H:%M:%S')${NC}" echo -e "${WHITE}配置文件: $CONFIG_FILE${NC}" echo -e "${WHITE}日志目錄: $LOG_DIR${NC}" echo # 顯示服務(wù)列表和狀態(tài) if [[ ${#SERVICE_NAMES[@]} -eq 0 ]]; then echo -e "${RED}未找到任何服務(wù)配置${NC}" else echo -e "${CYAN}================== 服務(wù)列表 ==================${NC}" printf "%-3s %-20s %-10s %-15s\n" "序號" "服務(wù)名稱" "端口" "狀態(tài)" echo "-----------------------------------------------" for ((i=0; i<${#SERVICE_NAMES[@]}; i++)); do status=$(check_service_status $i) printf "%-3s %-20s %-10s %s\n" "$((i+1))" "${SERVICE_NAMES[$i]}" "${SERVICE_PORTS[$i]}" "$status" done echo -e "${CYAN}===============================================${NC}" fi echo echo "操作選項:" echo "1-${#SERVICE_NAMES[@]}) 管理對應(yīng)服務(wù)" echo "b) 批量操作" echo "s) 系統(tǒng)信息" echo "r) 重新加載配置" echo "q) 退出程序" echo -e "${GREEN}#########################################################${NC}" read -p "請輸入選擇: " main_choice case $main_choice in [1-9]|[1-9][0-9]) index=$((main_choice-1)) if [[ $index -ge 0 && $index -lt ${#SERVICE_NAMES[@]} ]]; then service_management_menu $index else echo -e "${RED}無效的服務(wù)序號${NC}" sleep 1 fi ;; b|B) batch_operations_menu ;; s|S) show_system_info ;; r|R) echo -e "${BLUE}重新加載配置文件...${NC}" load_services echo -e "${GREEN}配置加載完成${NC}" sleep 1 ;; q|Q) echo -e "${GREEN}感謝使用SpringBoot服務(wù)管理器!${NC}" exit 0 ;; *) echo -e "${RED}無效選擇,請重新輸入${NC}" sleep 1 ;; esac done } # 檢查依賴命令 check_dependencies() { local missing_deps=() command -v java >/dev/null 2>&1 || missing_deps+=("java") command -v lsof >/dev/null 2>&1 || missing_deps+=("lsof") command -v nc >/dev/null 2>&1 || missing_deps+=("netcat") if [[ ${#missing_deps[@]} -ne 0 ]]; then echo -e "${RED}錯誤: 缺少必要的命令工具${NC}" echo "請安裝以下工具: ${missing_deps[*]}" echo echo "Ubuntu/Debian: sudo apt-get install openjdk-8-jdk lsof netcat" echo "CentOS/RHEL: sudo yum install java-1.8.0-openjdk lsof nc" exit 1 fi } # 主程序入口 main() { # 檢查依賴 check_dependencies # 加載服務(wù)配置 load_services # 顯示歡迎信息 clear echo -e "${GREEN}" echo "########################################################" echo "# #" echo "# SpringBoot服務(wù)管理器 v1.0 #" echo "# #" echo "# 支持多服務(wù)管理、日志查看、狀態(tài)監(jiān)控 #" echo "# #" echo "########################################################" echo -e "${NC}" sleep 2 # 啟動主菜單 main_menu } # 腳本執(zhí)行入口 if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then main "$@" fi
services.conf
# SpringBoot服務(wù)配置文件 # 格式: 服務(wù)名稱|JAR文件路徑|端口號|Profile環(huán)境|JVM參數(shù) # 示例配置,請根據(jù)實際情況修改 # 測試服務(wù) serveless-core|/opt/apps/serverless-core-1.0.0.jar|8080|prod|-Xms512m -Xmx1024m -XX:+UseG1GC # 注意事項: # 1. 每行一個服務(wù)配置 # 2. 使用 | 分隔各個字段 # 3. JAR文件路徑必須是絕對路徑 # 4. 端口號用于健康檢查 # 5. Profile環(huán)境可以為空,默認使用default # 6. JVM參數(shù)可以為空,使用默認配置 # 7. 以#開頭的行為注釋行
deploy.sh
# SpringBoot服務(wù)部署腳本 # 自動化部署和管理SpringBoot應(yīng)用 #!/bin/bash # 部署配置 APP_NAME="serverless-core" APP_VERSION="1.0.0" JAR_NAME="${APP_NAME}-${APP_VERSION}.jar" DEPLOY_DIR="/opt/apps" BACKUP_DIR="/opt/backups" SERVICE_PORT="8080" PROFILE="prod" # JVM參數(shù)配置 JVM_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC -XX:MaxGCPauseMillis=200" JVM_OPTS="$JVM_OPTS -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps" JVM_OPTS="$JVM_OPTS -Xloggc:$DEPLOY_DIR/logs/gc.log -XX:+UseGCLogFileRotation" JVM_OPTS="$JVM_OPTS -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=10M" # 顏色定義 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # 創(chuàng)建必要目錄 setup_directories() { echo -e "${BLUE}創(chuàng)建部署目錄...${NC}" mkdir -p "$DEPLOY_DIR" mkdir -p "$DEPLOY_DIR/logs" mkdir -p "$BACKUP_DIR" echo -e "${GREEN}目錄創(chuàng)建完成${NC}" } # 備份當前版本 backup_current_version() { if [[ -f "$DEPLOY_DIR/$JAR_NAME" ]]; then echo -e "${BLUE}備份當前版本...${NC}" local backup_file="$BACKUP_DIR/${JAR_NAME}.$(date +%Y%m%d_%H%M%S).bak" cp "$DEPLOY_DIR/$JAR_NAME" "$backup_file" echo -e "${GREEN}備份完成: $backup_file${NC}" fi } # 部署新版本 deploy_new_version() { local jar_file=$1 if [[ ! -f "$jar_file" ]]; then echo -e "${RED}錯誤: JAR文件不存在 - $jar_file${NC}" return 1 fi echo -e "${BLUE}部署新版本...${NC}" # 停止當前服務(wù) ./springboot-service-manager.sh stop "$APP_NAME" 2>/dev/null || true # 等待服務(wù)完全停止 sleep 3 # 復(fù)制新版本 cp "$jar_file" "$DEPLOY_DIR/$JAR_NAME" chmod +x "$DEPLOY_DIR/$JAR_NAME" echo -e "${GREEN}部署完成${NC}" } # 健康檢查 health_check() { local max_attempts=30 local attempt=0 echo -e "${BLUE}進行健康檢查...${NC}" while [[ $attempt -lt $max_attempts ]]; do if curl -s -f "http://localhost:$SERVICE_PORT/actuator/health" >/dev/null 2>&1; then echo -e "${GREEN}健康檢查通過!${NC}" return 0 fi attempt=$((attempt + 1)) echo -n "." sleep 2 done echo echo -e "${RED}健康檢查失??!${NC}" return 1 } # 回滾到上一版本 rollback() { echo -e "${YELLOW}開始回滾...${NC}" # 查找最新的備份文件 local latest_backup=$(ls -t "$BACKUP_DIR"/${JAR_NAME}.*.bak 2>/dev/null | head -1) if [[ -z "$latest_backup" ]]; then echo -e "${RED}沒有找到備份文件${NC}" return 1 fi echo -e "${BLUE}回滾到: $latest_backup${NC}" # 停止當前服務(wù) ./springboot-service-manager.sh stop "$APP_NAME" 2>/dev/null || true sleep 3 # 恢復(fù)備份 cp "$latest_backup" "$DEPLOY_DIR/$JAR_NAME" # 啟動服務(wù) ./springboot-service-manager.sh start "$APP_NAME" # 健康檢查 if health_check; then echo -e "${GREEN}回滾成功!${NC}" else echo -e "${RED}回滾后健康檢查失敗${NC}" return 1 fi } # 完整部署流程 full_deploy() { local jar_file=$1 echo -e "${GREEN}開始部署 $APP_NAME${NC}" echo "JAR文件: $jar_file" echo "部署目錄: $DEPLOY_DIR" echo "服務(wù)端口: $SERVICE_PORT" echo "環(huán)境配置: $PROFILE" echo "----------------------------------------" # 創(chuàng)建目錄 setup_directories # 備份當前版本 backup_current_version # 部署新版本 if ! deploy_new_version "$jar_file"; then echo -e "${RED}部署失敗${NC}" return 1 fi # 啟動服務(wù) echo -e "${BLUE}啟動服務(wù)...${NC}" ./springboot-service-manager.sh start "$APP_NAME" # 健康檢查 if health_check; then echo -e "${GREEN}部署成功!${NC}" # 清理舊備份(保留最近5個) echo -e "${BLUE}清理舊備份...${NC}" ls -t "$BACKUP_DIR"/${JAR_NAME}.*.bak 2>/dev/null | tail -n +6 | xargs rm -f echo -e "${GREEN}清理完成${NC}" else echo -e "${RED}部署失敗,開始回滾...${NC}" rollback return 1 fi } # 顯示使用幫助 show_help() { echo "SpringBoot應(yīng)用部署腳本" echo echo "用法:" echo " $0 deploy <jar-file> - 部署新版本" echo " $0 rollback - 回滾到上一版本" echo " $0 health - 健康檢查" echo " $0 setup - 初始化部署環(huán)境" echo echo "示例:" echo " $0 deploy app-1.0.0.jar" echo " $0 rollback" } # 主程序 main() { case "${1:-}" in deploy) if [[ -z "${2:-}" ]]; then echo -e "${RED}錯誤: 請指定JAR文件${NC}" show_help exit 1 fi full_deploy "$2" ;; rollback) rollback ;; health) health_check ;; setup) setup_directories ;; *) show_help ;; esac } main "$@"
以上就是SpringBoot利用可視化服務(wù)管理腳本部署應(yīng)用的詳細內(nèi)容,更多關(guān)于SpringBoot部署應(yīng)用的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring整合Quartz實現(xiàn)動態(tài)定時器的示例代碼
本篇文章主要介紹了Spring整合Quartz實現(xiàn)動態(tài)定時器的示例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-01-01springboot實現(xiàn)以代碼的方式配置sharding-jdbc水平分表
這篇文章主要介紹了springboot實現(xiàn)以代碼的方式配置sharding-jdbc水平分表,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11Java版數(shù)據(jù)結(jié)構(gòu)插入數(shù)據(jù)時遇到的結(jié)點為空的問題詳解
這篇文章主要介紹了Java版數(shù)據(jù)結(jié)構(gòu)插入數(shù)據(jù)時遇到的結(jié)點為空的問題及解決辦法,需要的朋友們可以學(xué)習(xí)下。2019-09-09Android開發(fā)Activity管理工具類的操作方法
這篇文章主要介紹了Android開發(fā)Activity管理工具類,下面是一個完整的Activity管理工具類實現(xiàn),可以幫助你管理應(yīng)用中的所有Activity,方便一鍵退出應(yīng)用、獲取當前Activity等操作,需要的朋友可以參考下2021-02-02Spring Boot 集成 MongoDB Template 的步驟
MongoDB 是一個流行的 NoSQL 數(shù)據(jù)庫,適合處理大量非結(jié)構(gòu)化數(shù)據(jù),本篇文章將詳細介紹如何在 Spring Boot 3.4.0 中集成 MongoDB Template,從零開始構(gòu)建一個簡單的應(yīng)用程序,感興趣的朋友一起看看吧2024-12-12Spring JPA事務(wù)管理與自定義操作實例解析(最新推薦)
在Spring框架中,數(shù)據(jù)持久化操作常常與事務(wù)管理緊密相關(guān),本文將深入探討Spring Data JPA中的事務(wù)管理機制,并結(jié)合具體實例,展示如何自定義事務(wù)行為以滿足不同的業(yè)務(wù)需求,感興趣的朋友一起看看吧2024-12-12