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ù)管理器 ####################
當(dāng)前時間: 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)標(biāo)識。
智能服務(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)確認(rèn)
安全停止流程:
發(fā)送TERM信號 → 等待優(yōu)雅停止 → 超時強制終止 → 狀態(tài)確認(rèn)
這種機制確保服務(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. 版本備份:自動備份當(dāng)前運行版本
3. 服務(wù)停止:優(yōu)雅停止當(dāng)前服務(wù)
4. 文件部署:復(fù)制新版本到部署目錄
5. 服務(wù)啟動:啟動新版本服務(wù)
6. 健康檢查:驗證服務(wù)是否正常運行
7. 清理備份:保留最近5個版本備份
安全回滾機制
當(dāng)部署出現(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ā)布前:
# 查看當(dāng)前所有服務(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)急處理
當(dā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)鍵指標(biāo)告警
建立故障處理流程
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:-默認(rèn)}"
echo -e "${WHITE}JVM參數(shù):${NC} ${jvm_opts:-默認(rèn)}"
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 "當(dāng)前狀態(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}當(dāng)前時間: $(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)境可以為空,默認(rèn)使用default # 6. JVM參數(shù)可以為空,使用默認(rèn)配置 # 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}"
}
# 備份當(dāng)前版本
backup_current_version() {
if [[ -f "$DEPLOY_DIR/$JAR_NAME" ]]; then
echo -e "${BLUE}備份當(dāng)前版本...${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}"
# 停止當(dāng)前服務(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}"
# 停止當(dāng)前服務(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
# 備份當(dāng)前版本
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-01
springboot實現(xiàn)以代碼的方式配置sharding-jdbc水平分表
這篇文章主要介紹了springboot實現(xiàn)以代碼的方式配置sharding-jdbc水平分表,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11
Java版數(shù)據(jù)結(jié)構(gòu)插入數(shù)據(jù)時遇到的結(jié)點為空的問題詳解
這篇文章主要介紹了Java版數(shù)據(jù)結(jié)構(gòu)插入數(shù)據(jù)時遇到的結(jié)點為空的問題及解決辦法,需要的朋友們可以學(xué)習(xí)下。2019-09-09
Android開發(fā)Activity管理工具類的操作方法
這篇文章主要介紹了Android開發(fā)Activity管理工具類,下面是一個完整的Activity管理工具類實現(xiàn),可以幫助你管理應(yīng)用中的所有Activity,方便一鍵退出應(yīng)用、獲取當(dāng)前Activity等操作,需要的朋友可以參考下2021-02-02
Spring 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-12
Spring JPA事務(wù)管理與自定義操作實例解析(最新推薦)
在Spring框架中,數(shù)據(jù)持久化操作常常與事務(wù)管理緊密相關(guān),本文將深入探討Spring Data JPA中的事務(wù)管理機制,并結(jié)合具體實例,展示如何自定義事務(wù)行為以滿足不同的業(yè)務(wù)需求,感興趣的朋友一起看看吧2024-12-12

