Supervisord 管理 Java 服务的完整方案
安装 Supervisord
# Ubuntu/Debian
sudo apt update && sudo apt install -y supervisor
# CentOS/RHEL
sudo yum install -y supervisor
sudo systemctl enable supervisord
sudo systemctl start supervisord
验证安装
sudo supervisorctl status
ps -ef | grep supervisord
配置 Java 服务
创建配置文件 /etc/supervisor/conf.d/my-java-app.conf
[program:my-java-app]
# 基础配置
command=java -Xms512m -Xmx1024m -jar /opt/app/my-app.jar
directory=/opt/app
user=appuser
autostart=true
autorestart=true
startsecs=30
startretries=3
# 日志管理
stdout_logfile=/var/log/my-java-app/stdout.log
stdout_logfile_maxbytes=50MB
stdout_logfile_backups=10
stderr_logfile=/var/log/my-java-app/stderr.log
stderr_logfile_maxbytes=50MB
stderr_logfile_backups=10
# 环境变量
environment=JAVA_HOME="/usr/lib/jvm/java-11-openjdk",SPRING_PROFILES_ACTIVE="prod"
# 进程管理
stopsignal=INT
stopwaitsecs=30
killasgroup=true
高级配置选项
# 资源限制
priority=500 ; 进程优先级
numprocs=1 ; 进程数量
# 安全控制
umask=022
serverurl=AUTO
# 事件通知
events=PROCESS_STATE_FATAL ; 配置事件触发告警
服务管理命令
# 重新加载配置
sudo supervisorctl reread
sudo supervisorctl update
# 服务控制
sudo supervisorctl start my-java-app
sudo supervisorctl stop my-java-app
sudo supervisorctl restart my-java-app
# 查看状态
sudo supervisorctl status my-java-app
sudo supervisorctl tail -f my-java-app stderr
批量操作
# 启动所有服务
sudo supervisorctl start all
# 停止所有服务
sudo supervisorctl stop all
# 重启所有服务
sudo supervisorctl restart all
Prometheus 监控集成
# 在supervisord.conf中启用HTTP接口
[inet_http_server]
port = 0.0.0.0:9001
username = monitor
password = yourpassword
告警规则示例
# Prometheus alert.rules
groups:
- name: java-service-alerts
rules:
- alert: JavaServiceDown
expr: up{job="my-java-app"} == 0
for: 2m
labels:
severity: critical
annotations:
summary: "Java服务 {{ $labels.instance }} 已宕机"
description: "服务 {{ $labels.job }} 已停止响应超过2分钟"
自定义健康检查
# 在Java应用中添加健康接口
@RestController
public class HealthController {
@GetMapping("/health")
public String health() {
return "OK";
}
}
# Supervisord配置健康检查
[program:my-java-app]
healthcheck=curl -fs http://localhost:8080/health || exit 1
healthcheck_interval=60
日志管理方案
创建 /etc/logrotate.d/my-java-app:
/var/log/my-java-app/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 640 appuser appuser
sharedscripts
postrotate
/usr/bin/supervisorctl signal HUP my-java-app >/dev/null 2>&1 || true
endscript
}
ELK 集成方案
# 修改Supervisord日志输出为JSON格式
stdout_logfile=/var/log/my-java-app/app.log
stdout_logfile_format=json
多实例部署
[program:my-java-app]
process_name=%(program_name)s_%(process_num)02d
numprocs=4
command=java -jar /opt/app/my-app.jar --server.port=808%(process_num)02d
依赖服务控制
[group:app-group]
programs=my-java-app,redis-server,mysql-server
[program:redis-server]
command=/usr/bin/redis-server
[program:mysql-server]
command=/usr/bin/mysqld_safe
自定义启动脚本
#!/bin/bash
# /opt/app/start-app.sh
# 检查端口占用
if netstat -tln | grep -q ':8080'; then
echo "Port 8080 already in use!"
exit 1
fi
# 启动Java服务
exec java -jar /opt/app/my-app.jar
对应Supervisord配置:
command=/bin/bash /opt/app/start-app.sh
安全加固措施
# 创建专用用户
sudo useradd -r -s /bin/false appuser
sudo chown -R appuser:appuser /opt/app
sudo chmod 750 /opt/app
[inet_http_server]
port = 127.0.0.1:9001 ; 仅允许本地访问
[program:my-java-app]
priority=100 ; 降低CPU优先级
minfds=1024 ; 最小文件描述符
minprocs=200 ; 最小进程数
故障排查指南
# 查看详细日志
sudo supervisorctl fg my-java-app
# 检查启动错误
journalctl -u supervisord -n 50 -f
# 手动测试启动
sudo -u appuser java -jar /opt/app/my-app.jar
# 检查端口冲突
ss -tlnp | grep java
自动恢复策略
[program:my-java-app]
autorestart=true
startretries=5
exitcodes=0,2 ; 只有退出码为0或2时重启
stopasgroup=true ; 停止整个进程组
性能优化建议
command=java -server -Xms2g -Xmx2g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar /opt/app/my-app.jar
Supervisord 调优
[supervisord]
minfds=65535 ; 最大文件描述符
minprocs=2000 ; 最大进程数
一键部署脚本
#!/bin/bash
# deploy-java-with-supervisor.sh
APP_NAME="my-java-app"
APP_JAR="/opt/app/my-app.jar"
APP_USER="appuser"
JAVA_OPTS="-Xms2g -Xmx2g -XX:+UseG1GC"
echo "开始部署Java服务托管..."
# 1. 创建用户和目录
sudo useradd -r -s /bin/false $APP_USER
sudo mkdir -p /opt/app /var/log/$APP_NAME
sudo chown $APP_USER:$APP_USER /opt/app /var/log/$APP_NAME
# 2. 创建Supervisor配置
sudo tee /etc/supervisor/conf.d/$APP_NAME.conf > /dev/null <<EOF
[program:$APP_NAME]
command=java $JAVA_OPTS -jar $APP_JAR
directory=/opt/app
user=$APP_USER
autostart=true
autorestart=true
startsecs=30
stdout_logfile=/var/log/$APP_NAME/stdout.log
stderr_logfile=/var/log/$APP_NAME/stderr.log
environment=JAVA_HOME="/usr/lib/jvm/java-11-openjdk"
EOF
# 3. 重载配置
sudo supervisorctl reread
sudo supervisorctl update
echo "部署完成!使用以下命令管理服务:"
echo "启动服务: sudo supervisorctl start $APP_NAME"
echo "查看状态: sudo supervisorctl status"
更多推荐
所有评论(0)