Monit脚本无法重启Preview Service问题求助
你已经把监控脚本和Monit配置的基础逻辑都跑通了——手动测试脚本退出码符合预期,CLI下spark用户也能正常启停服务,但Monit触发后服务就是起不来,核心问题大概率出在Monit执行脚本时的上下文和sudo的权限/环境变量差异上。我给你几个针对性的排查方向:
去掉sudo,直接用spark用户启动服务
既然你已经确认spark用户无需sudo就能正常运行/opt/previewservice/preview-service.sh start,那完全没必要在testi.sh里加sudo。直接修改testi.sh的启动命令:# 替换原来的sudo行 bash /opt/previewservice/preview-service.sh start这是最直接的解决方案,避免sudo带来的所有权限和环境变量问题。毕竟Monit本身就是以spark用户运行的,直接执行脚本即可继承spark的权限。
检查sudo执行时的环境变量丢失问题
如果一定要保留sudo(比如脚本里有其他需要root权限的操作),那大概率是sudo执行时丢失了preview-service.sh依赖的环境变量。可以做两个调整:- 修改/etc/sudoers配置,允许spark用户保留环境变量执行该脚本:
spark ALL=(ALL) NOPASSWD: SETENV: /opt/previewservice/preview-service.sh - 在testi.sh里的sudo命令加上
-E参数保留环境变量:sudo -E bash /opt/previewservice/preview-service.sh start
- 修改/etc/sudoers配置,允许spark用户保留环境变量执行该脚本:
查看preview-service.sh的启动日志,定位具体错误
日志只显示testi.sh执行了,但不知道preview-service.sh启动时有没有报错。把启动命令的输出重定向到日志文件,就能看到具体问题:# 在testi.sh里修改启动行 bash /opt/previewservice/preview-service.sh start >> /tmp/preview-start.log 2>&1比如端口被占用、依赖的程序不在PATH里、配置文件权限不足等,都会在这个日志里体现。
确认Monit执行脚本的工作目录
Monit执行脚本时的默认工作目录可能不是/opt/previewservice,如果preview-service.sh里用了相对路径(比如引用同目录下的配置文件),就会出错。可以在preview-service.sh开头加上:# 切换到脚本所在目录 cd "$(dirname "$0")" || exit 1或者在testi.sh里指定工作目录后再启动:
bash -c "cd /opt/previewservice && ./preview-service.sh start"验证Monit执行时的用户上下文
有时候Monit配置的运行用户可能没有正确生效,或者执行时的环境和手动运行时不一样。可以在testi.sh里加一行调试信息:dt=$(date '+%d/%m/%Y %H:%M:%S'); echo "[$dt] Running as user: $(whoami), Working dir: $(pwd), Env: $(echo $PATH)" >> /tmp/testi-debug.log对比spark手动运行testi.sh时的输出,看看用户、工作目录、环境变量有没有差异。
优先试试第一个方案(去掉sudo),因为它最简洁,也最符合你已经验证过的权限逻辑。如果还是不行,查看启动日志是最有效的排查方式——毕竟服务没起来肯定有具体的错误信息,找到它就能快速解决问题。
内容的提问来源于stack exchange,提问作者JTM

