问题现象:
saltstack 执行 cmd.run python 服务,会 hang 住。
但应用服务器上的服务是启动了。
也就是说,saltstack cmd.run 时无法正常退出,要手工执行 Ctrl-C 来退出。
原因分析:
// 使用 -l debug 参数启用 saltstack debug 日志
# salt 'xxxxxx01013' cmd.run "/data/apps/xx-xxxxx-service/xx-xxxxx-service_start.sh" -l debug
省略其他输出……
[DEBUG ] Closing AsyncZeroMQReqChannel instance
[DEBUG ] Passing on saltutil error. Key 'u'retcode' missing from client return. This may be an error in the client.
[DEBUG ] Checking whether jid 20201225142021496381 is still running
[DEBUG ] Initializing new AsyncZeroMQReqChannel for (u'/etc/salt/pki/master', u'xxxxxx01002_master', u'tcp://10.1.9.xx:4506', u'clear')
[DEBUG ] Connecting the Minion to the Master URI (for the return server): tcp://10.1.9.xx:4506
[DEBUG ] Trying to connect to: tcp://10.1.9.xx:4506
[DEBUG ] Closing AsyncZeroMQReqChannel instance
[DEBUG ] Passing on saltutil error. Key 'u'retcode' missing from client return. This may be an error in the client.
[DEBUG ] Checking whether jid 20201225142021496381 is still running
[DEBUG ] Initializing new AsyncZeroMQReqChannel for (u'/etc/salt/pki/master', u'xxxxxx01002_master', u'tcp://10.1.9.xx:4506', u'clear')
[DEBUG ] Connecting the Minion to the Master URI (for the return server): tcp://10.1.9.xx:4506
[DEBUG ] Trying to connect to: tcp://10.1.9.xx:4506
[DEBUG ] Closing AsyncZeroMQReqChannel instance
[DEBUG ] Passing on saltutil error. Key 'u'retcode' missing from client return. This may be an error in the client.
使用 -l debug 参数启用 saltstack debug 日志,可以看到是因为 xx-xxxxx-service_start.sh 启动脚本没有返回执行结果给 saltstack,导致 saltstack 一直在等待返回结果。
# cat xx-xxxxx-service_start.sh
#!/bin/bash
. /etc/profile
. /usr/local/miniconda3/etc/profile.d/conda.sh
conda activate xx-xxxxx-service
cd /data/apps/xx-xxxxx-service
nohup python manage.py runserver 0.0.0.0:25074 &
查看 xx-xxxxx-service_start.sh 启动脚本,可以知道 python 服务是直接 nohup python manage.py runserver 0.0.0.0:25074 &
启动的,saltstack 无法正确处理这条命令。
原因是 nohup python manage.py runserver 0.0.0.0:25074 &
方式启动,还会生成一个 nohup.out 文件,启动运行日志都会持续输出到此文件。导致的问题就是,命令还在运行中,没有退出,所以没有返回结果给 saltstack。
解决办法:
方式一:
修改脚本,nohup 配合 >/dev/null 2>&1
使用,就可以解决。
# cat xx-xxxxx-service_start.sh
省略其他输出……
nohup python manage.py runserver 0.0.0.0:25074 >/dev/null 2>&1 &
方式二:
利用 uwsgi
或者其他 python web server(gunicorn 等) 或者 systemctl
来后台运行 python 服务,由这些服务返回结果给 saltstack。
// uwsgi 配置文件示例
# cat xx-xxxxx-service.ini
[uwsgi]
http = :25074
chdir = /data/apps/xx-xxxxx-service
wsgi-file = /data/apps/xx-xxxxx-service/foobar/wsgi.py
processes = 1
threads = 2
stats = 127.0.0.1:9999
vacuum = true
daemonize = /data/logs/xx-xxxxx-service/xx-xxxxx-service.log
pidfile = /data/apps/xx-xxxxx-service/foobar/foobar.pid
master = true
lazy-apps = true
// uwsgi 启动脚本示例
# cat start.sh
#!/bin/bash
. /etc/profile
. /usr/local/miniconda3/etc/profile.d/conda.sh
conda activate xx-xxxxx-service
cd /data/apps/xx-xxxxx-service
uwsgi --ini /data/apps/xx-xxxxx-service/xx-xxxxx-service.ini