使用supervisor运行Python脚本

4
我从这里复制了一些内容,以便将我的Python代码作为守护进程运行。为了实现更长的正常运行时间,我认为最好使用supervisor维持此守护进程的运行。
我执行了以下操作。 python_deamon.conf
[program:python_deamon]
directory=/usr/local/python_deamon/
command=/usr/local/python_venv/bin/python daemon_runnner.py start
stderr_logfile=/var/log/gunicorn.log
stdout_logfile=/var/log/gunicorn.log
autostart=true
autorestart=true

问题在于,尽管supervisor成功启动了python_daemon,但它仍在不断重试。
2015-09-23 16:10:45,592 CRIT Supervisor running as root (no user in config file)
2015-09-23 16:10:45,592 WARN Included extra file "/etc/supervisor/conf.d/python_daemon.conf" during parsing
2015-09-23 16:10:45,592 INFO RPC interface 'supervisor' initialized
2015-09-23 16:10:45,592 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2015-09-23 16:10:45,592 INFO supervisord started with pid 13880
2015-09-23 16:10:46,595 INFO spawned: 'python_deamon' with pid 17884
2015-09-23 16:10:46,611 INFO exited: python_deamon (exit status 1; not expected)
2015-09-23 16:10:47,614 INFO spawned: 'python_deamon' with pid 17885
2015-09-23 16:10:47,630 INFO exited: python_deamon (exit status 1; not expected)
2015-09-23 16:10:49,635 INFO spawned: 'python_deamon' with pid 17888
2015-09-23 16:10:49,656 INFO exited: python_deamon (exit status 1; not expected)
2015-09-23 16:10:52,662 INFO spawned: 'python_deamon' with pid 17891
2015-09-23 16:10:52,680 INFO exited: python_deamon (exit status 1; not expected)
2015-09-23 16:10:53,681 INFO gave up: python_deamon entered FATAL state, too many start retries too quickly

只是为了记录,覆盖run()方法后我从来没有返回任何东西。
我正在尝试做的事情可能有可能吗?还是我很愚蠢?
P.S:我知道整个问题的根本原因是因为run()从不返回任何内容,所以监管者一直在尝试启动它,因此认为进程失败并将状态设置为FATAL Exited too quickly (process log may have details)。我的实际问题是我这样做对吗?还是可以用这种方式完成?
P.P.S:独立运行(无监管者)的daemon_runnner.py在有sudo权限和没有sudo权限时都可以正常运行。

你有没有在不以守护进程形式运行daemon_runner.py的情况下进行过测试?它返回状态码1。 - wenzul
5个回答

6
尝试将startsecs设置为0:
[program:foo]
command = ls
startsecs = 0
autorestart = false
http://supervisord.org/configuration.html

startsecs

程序启动后需要保持运行的总秒数,以确定启动是否成功。如果程序在启动后没有保持这么多秒的运行时间,即使它以“预期”的退出代码(参见exitcodes)退出,启动也将被视为失败。将其设置为0表示程序无需保持任何特定时间的运行。

2
这是我通常的做法:
  • 创建一个service.conf文件,描述新的Python脚本。该脚本引用了实际启动Python脚本的shell脚本。这个.conf文件位于/etc/supervisor/conf.d/目录下。
  • 创建一个启动Python脚本的shell脚本。更改权限为可执行。chmod 755 service.sh。在这个脚本中,我们实际上启动了Python脚本。
  • 配置log_stderrstderr_logfile以验证问题。
  • 使用reload更新supervisor,然后检查状态:

supervisor> status

alexad RUNNING pid 32657, uptime 0:21:05

service.conf

[program:alexad]
; Set full path to celery program if using virtualenv

command=sh /usr/local/src/gonzo/supervisorctl/alexad.sh
directory=/usr/local/src/gonzo/services/alexa
log_stdout=true             ; if true, log program stdout (default true)
log_stderr=true             ; if true, log program stderr (default false)
stderr_logfile=/usr/local/src/gonzo/log/alexad.err
logfile=/usr/local/src/gonzo/log/alexad.log
autostart=true
autorestart=true
startsecs=10

; Need to wait for currently executing tasks to finish at shutdown.
; Increase this if you have very long running tasks.
stopwaitsecs = 600

; When resorting to send SIGKILL to the program to terminate it
; send SIGKILL to its whole process group instead,
; taking care of its children as well.
killasgroup=true

; Set Celery priority higher than default (999)
priority=500

service.sh

#!/bin/bash
cd /usr/local/src/gonzo/services/alexa
exec python reader.py

1

您应该检查通常位于此处的主管程序日志/var/log/supervisor/

在我的情况下,我遇到了一个ModuleNotFoundError: No module named 'somemodule'

我发现这很奇怪,因为当我直接运行脚本时它正常工作。

尝试使用sudo运行脚本后,我意识到了正在发生的事情。

Python导入是特定于用户而不是文件夹的。因此,如果您使用当前登录的用户安装python或pip并尝试以sudo或其他用户身份运行相同的脚本,则可能会返回ModuleNotFoundError: No module named 'somemodule'

默认情况下,Supervisor以root身份运行

我通过将supervisor配置文件中的user设置为当前用户(在我的情况下为ubuntu)来解决了这个问题:

[program:some_program]
directory=/home/ubuntu/scripts/
command=/usr/bin/python3 myscript.py
autostart=true
autorestart=true
user=ubuntu
stderr_logfile=/var/log/supervisor/myscriptlogs.err.log
stdout_logfile=/var/log/supervisor/myscriptlogs.out.log

作为副注,确保您的Supervisor命令调用所需版本的Python脚本也是非常重要的。
进入脚本所在的文件夹并运行which python命令,使用返回结果。

0

你的脚本出现了退出状态错误。Supervisor 只是试图重新启动脚本。

Supervisor 是以 root 权限启动的,也许它将这些权限授予了你的脚本,导致它失败(源目录发生了变化或其他原因)。请检查在没有 Supervisor 的情况下以 root 用户身份运行守护进程时会发生什么。

我们真的需要更多信息才能知道它为什么失败。


-1

不确定是否与守护进程运行器的问题相同,但如果您直接使用守护进程上下文并使用supervisord,则需要将context.detach_process设置为False


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接