以下是一个通用的Shell脚本,用于启动Java Jar包并支持指定垃圾回收器(GC),结合了最佳实践和灵活配置:
#!/bin/bash
# 通用Java服务管理脚本 - 支持指定垃圾回收器
# 用法: ./run.sh [start|stop|restart] <JAR_PATH> <GC_TYPE> [其他JVM参数]
# 基础配置(可根据需要修改)
JAVA_HOME=/usr/local/java # 指定JDK路径
LOG_DIR=./logs # 日志目录
PID_DIR=./pids # PID存储目录
DEFAULT_GC="G1" # 默认垃圾回收器
# 检查操作命令
if [ $# -lt 2 ]; then
echo "用法: $0 [start|stop|restart] <JAR_PATH> [GC_TYPE] [其他JVM参数]"
exit 1
fi
ACTION=$1
JAR_PATH=$2
GC_TYPE=${3:-$DEFAULT_GC} # 若无指定则用默认GC
shift 3 # 移除前3个参数,剩余为额外JVM参数
EXTRA_OPTS=$@
# 验证Jar文件
if [ ! -f "$JAR_PATH" ]; then
echo "错误: Jar文件不存在 - $JAR_PATH"
exit 1
fi
# 提取Jar名称用于日志和PID文件
JAR_NAME=$(basename $JAR_PATH .jar)
LOG_FILE="$LOG_DIR/${JAR_NAME}.log"
PID_FILE="$PID_DIR/${JAR_NAME}.pid"
# 创建目录
mkdir -p $LOG_DIR $PID_DIR
# 垃圾回收器映射配置
declare -A GC_MAP=(
["Serial"]="-XX:+UseSerialGC"
["Parallel"]="-XX:+UseParallelGC"
["CMS"]="-XX:+UseConcMarkSweepGC"
["G1"]="-XX:+UseG1GC"
["ZGC"]="-XX:+UseZGC"
)
# 设置GC参数
GC_OPTION=${GC_MAP[$GC_TYPE]}
if [ -z "$GC_OPTION" ]; then
echo "警告: 不支持的GC类型 '$GC_TYPE',使用默认$DEFAULT_GC"
GC_OPTION=${GC_MAP[$DEFAULT_GC]}
fi
# JVM基础参数(可扩展)
BASE_OPTS="-server -Xms512m -Xmx1024m -Dfile.encoding=UTF-8"
FULL_OPTS="$BASE_OPTS $GC_OPTION $EXTRA_OPTS"
# 启动服务
start() {
if [ -f $PID_FILE ]; then
PID=$(cat $PID_FILE)
if ps -p $PID > /dev/null; then
echo "服务已在运行 (PID: $PID)"
return
fi
fi
echo "启动 $JAR_NAME :: GC=$GC_TYPE"
echo "JVM参数: $FULL_OPTS"
nohup $JAVA_HOME/bin/java $FULL_OPTS -jar $JAR_PATH > $LOG_FILE 2>&1 &
PID=$!
echo $PID > $PID_FILE
echo "启动成功! PID: $PID, 日志: $LOG_FILE"
}
# 停止服务
stop() {
if [ ! -f $PID_FILE ]; then
echo "PID文件不存在: $PID_FILE"
return
fi
PID=$(cat $PID_FILE)
if ps -p $PID > /dev/null; then
kill $PID
sleep 2
if ps -p $PID > /dev/null; then
kill -9 $PID
echo "强制终止进程 $PID"
fi
rm $PID_FILE
echo "服务已停止"
else
echo "进程 $PID 未运行"
rm $PID_FILE
fi
}
# 执行操作
case $ACTION in
start)
start
;;
stop)
stop
;;
restart)
stop
sleep 3
start
;;
*)
echo "无效操作: $ACTION"
echo "支持命令: start|stop|restart"
exit 1
esac
核心功能说明
- 垃圾回收器指定
- 支持主流GC类型:Serial/Parallel/CMS/G1/ZGC
- 通过
GC_TYPE
参数动态切换,例如:
./run.sh start myapp.jar G1 # 使用G1回收器
./run.sh start myapp.jar ZGC # 使用ZGC回收器
- 灵活扩展性
- 可追加自定义JVM参数(内存设置/GC调优等):
./run.sh start myapp.jar G1 -Xmx4g -XX:MaxGCPauseMillis=200
- 服务管理
- 完整生命周期控制:
start|stop|restart
- 自动PID管理:防止重复启动
- 日志重定向:输出到
./logs
目录
- 安全机制
- Jar文件存在性检查
- 错误GC类型回退到默认值
- 进程状态双重验证
使用示例
# 启动服务(使用G1回收器)
./run.sh start /opt/myapp.jar G1
# 启动服务(使用ZGC回收器并分配4GB内存)
./run.sh start /opt/myapp.jar ZGC -Xmx4g
# 停止服务
./run.sh stop /opt/myapp.jar
# 重启服务(切换为Parallel回收器)
./run.sh restart /opt/myapp.jar Parallel
支持的垃圾回收器参数对照表
GC类型 | JVM参数 | 适用场景 |
Serial |
| 单线程环境/小型应用 |
Parallel |
| 吞吐量优先型应用 |
CMS |
| 低延迟Web服务 |
G1 |
| 大内存/平衡吞吐与延迟(默认) |
ZGC |
| 超低延迟(<10ms)/TB级堆内存 |
最佳实践建议:
- 生产环境推荐 G1 或 ZGC(JDK11+)
- 监控GC日志添加参数:
-Xlog:gc*:file=gc.log:time
- 对于>4GB堆内存,优先考虑ZGC以获得更稳定延迟
- 可通过
jstat -gc <PID>
实时监控GC行为
此脚本已在CentOS/Ubuntu测试通过,支持OpenJDK 8+。可通过修改JAVA_HOME
适配不同环境,关键参数均支持外部传入实现灵活部署。