在配置自动守护之前,必须先搞清楚服务为什么会挂,否则盲目重启只会掩盖问题,导致日志爆炸。以下是Linux环境下最核心的三个排查步骤。
绝大多数服务异常退出是因为内存溢出(OOM)。Linux内核的OOM Killer机制会在内存耗尽时强行杀掉占用内存最大的进程,通常就是你的业务服务。
执行以下命令查看内核日志中是否包含OOM记录:
```bash dmesg | grep -i "out of memory" | tail -n 20 ```或者查看更通用的系统日志:
```bash journalctl -k | grep -i "killed process" ```如果输出中显示 Out of memory: Kill process,说明服务器内存不足。此时需要检查内存使用情况:
```bash free -h ```解决方案:增加服务器Swap空间、增加物理内存,或者优化应用程序内存泄漏。
如果你的服务是通过Systemd管理的(现代Linux发行版默认方式),这是最直接的日志来源。将下面的 your-service-name 替换为你的实际服务名。
```bash journalctl -u your-service-name -n 50 --no-pager ```参数说明:-n 50 表示只看最后50行;--no-pager 表示直接输出到屏幕,不需要按空格翻页。
重点关注日志末尾的 exit code(退出码):
如果Systemd日志没有提供足够的信息,你需要去应用目录下找日志文件。通常位于 /var/log/ 或者应用目录下的 logs/ 文件夹。
使用tail命令实时监控日志,尝试复现问题:
```bash tail -f /path/to/your/application.log ```Systemd是Linux下最稳定、开销最小的进程守护方案。它不需要你写额外的脚本,只需修改配置文件即可实现服务崩溃后自动重启。
找到你的服务配置文件。通常位于 /etc/systemd/system/ 目录下,以 .service 结尾。如果没有,你需要新建一个。
执行命令编辑(请将 my-app 替换为你的服务名):
```bash vim /etc/systemd/system/my-app.service ```以下是必须包含的完整配置内容。请确保 [Service] 部分的配置正确,这是实现自动重启的核心:
```ini [Unit] Description=My Application Service After=network.target [Service] 指定运行用户,建议不要用root User=www-data Group=www-data 指定工作目录 WorkingDirectory=/opt/my-app 启动命令,这里以Java应用为例,请替换为实际的启动命令 ExecStart=/usr/bin/java -jar /opt/my-app/app.jar 重启策略:on-failure 表示只有在非正常退出时才重启 Restart=on-failure 重启前等待时间,建议设置为5秒或10秒,避免频繁重启耗尽资源 RestartSec=5s 配置重启次数限制,防止无限重启导致CPU飙高 10秒内如果重启超过5次,就放弃重启 StartLimitInterval=10s StartLimitBurst=5 标准输出和错误输出重定向到文件(可选,方便排错) StandardOutput=append:/var/log/my-app/stdout.log StandardError=append:/var/log/my-app/stderr.log [Install] WantedBy=multi-user.target ```配置文件中的 Restart 参数决定了重启行为,必须根据业务场景设置:
配置修改完成后,必须执行以下命令让Systemd重载配置:
```bash systemctl daemon-reload ```然后重新启动服务并开启开机自启:
```bash systemctl enable my-app systemctl restart my-app ```
如果你的环境非常老旧,不支持Systemd,或者你需要监控一个非Service管理的第三方二进制程序,可以使用Shell脚本配合Crontab实现守护。
创建一个脚本文件,例如 /root/watch_process.sh:
```bash vim /root/watch_process.sh ```写入以下内容(注意替换 APP_NAME 和 START_CMD):
```bash !/bin/bash 配置部分 APP_NAME="nginx" START_CMD="/usr/sbin/nginx" LOG_FILE="/var/log/watch_process.log" 检查进程是否存在 pgrep -x 会精确匹配进程名 if ! pgrep -x "$APP_NAME" > /dev/null then echo "$(date '+%Y-%m-%d %H:%M:%S') - $APP_NAME is not running, restarting..." >> $LOG_FILE 执行启动命令 nohup $START_CMD >> $LOG_FILE 2>&1 & echo "$(date '+%Y-%m-%d %H:%M:%S') - $APP_NAME started." >> $LOG_FILE else 进程存在时不做操作,避免刷屏日志 : fi ```赋予脚本执行权限:
```bash chmod +x /root/watch_process.sh ```编辑当前用户的定时任务:
```bash crontab -e ```在文件末尾添加一行,表示每分钟检查一次:
```bash /root/watch_process.sh ```如果你的服务运行在Docker容器中,配置重启策略比Systemd更简单。
在使用 docker run 命令时,添加 --restart 参数:
```bash docker run -d \ --name my-nginx \ --restart unless-stopped \ nginx:latest ```参数解释:
在 docker-compose.yml 文件中,添加 restart 字段:
```yaml version: '3' services: web: image: nginx:latest ports: - "80:80" restart: unless-stopped ```更新配置:
```bash docker-compose up -d ```配置完自动重启后,不要等到下次崩溃才验证,现在就手动模拟崩溃,测试配置是否有效。
找到你的服务主进程PID:
```bash ps -ef | grep my-app ```直接使用 kill -9 强杀进程:
```bash kill -9紧接着查看服务状态:
```bash systemctl status my-app ```如果配置成功,你应该看到 Active: active (running),且日志中会显示服务被重启了。观察 Restart 计数是否增加。
强制停止并删除容器:
```bash docker stop my-nginx docker rm my-nginx ```如果配置了 restart: unless-stopped 或 always,执行完rm命令后,容器会瞬间消失然后自动重新创建并启动。查看 docker ps 即可验证。
下一篇: 服务器负载趋势查看
易频IT社区是综合性互联网IT技术门户网站,专注分享网络技术、服务器运维、网络安全、编程开发、系统架构、云计算、大数据等行业干货,实时更新IT行业资讯、零基础教程、实战案例,为IT从业者、技术爱好者提供专业的学习交流平台。
Copyright © 2021-2026 易频IT社区. All Rights Reserved. 备案号:闽ICP备2023013482号 网站地图