我有一个使用 Falcon Framework 用 python 构建的小型 rest api,它在带有 gunicorn + gevent 和 pypy 2.3 的虚拟环境中运行(我成功地安装了来自 gevent@pypy-hacks 和 gevent-on-pypy/pypycore 的 pip 包)。我想为我的应用程序添加一个"主管",所以我首先安装了 supervisord,然后按照步骤启动并运行它。
我在服务器中做的第一件事是测试启动 api 的命令;它运行成功,我可以毫无问题地使用 api。该命令是:
/bin/bash -c 'cd /path/to/project/api && /path/to/project/env/bin/gunicorn -c settings.py my-api:my_api'
注意:settings.py 我设置了参数daemon=False
,因为我看到主管要求命令在"前台"运行而不是守护程序。
一旦它起作用,我继续创建应用程序的/etc/supervisor/conf.d/my_api.conf
conf文件,并将"command"参数设置为我成功运行的上述命令。当我尝试通过主管启动 API 时,它失败了,并且在 API 的日志中,错误是:
Traceback (most recent call last):
File "/path/to/project/env/site-packages/gunicorn/arbiter.py", line 507, in spawn_worker
worker.init_process()
File "/path/to/project/env/site-packages/gunicorn/workers/ggevent.py", line 185, in init_process
self.patch()
File "/path/to/project/env/site-packages/gunicorn/workers/ggevent.py", line 74, in patch
_sock=s))
File "/path/to/project/env/site-packages/gevent/socket.py", line 240, in __init__
self.hub = get_hub()
File "/path/to/project/env/site-packages/gevent/hub.py", line 169, in get_hub
hub = _threadlocal.hub = hubtype(*args, **kwargs)
File "/path/to/project/env/site-packages/gevent/hub.py", line 268, in __init__
loop_class = _import(self.loop_class)
File "/path/to/project/env/site-packages/gevent/hub.py", line 198, in _import
return _import(path[-1])
File "/path/to/project/env/site-packages/gevent/hub.py", line 210, in _import
x = __import__(module)
ImportError: No module named gevent.core
所以,我很惊讶手动运行命令确实有效,但是当主管尝试运行它时,抛出了上述错误。
经过大量的试验和错误,我决定安装 monit 看看它是否可以监控我的 api,我确实成功地设置了它,将"启动程序"参数指定为上述命令。
我很惊讶monit抛出了完全相同的错误。那么,这是否意味着我的 api(pypy + gunicorn + gevent)的性质阻止了自己被周围的任何监控软件监控?
配置主管/监控时我做错了什么吗?
任何帮助将不胜感激。
事实证明,我已经将环境变量GEVENT_LOOP导出到我的/etc/environment
中,如下所示:
export GEVENT_LOOP=pypycore.loop
由于要在pypy上运行gevent,因此需要一些黑客,包括上述导出。
但是我需要在Monit的"start_program"命令条目中手动导出它(最后我坚持使用Monit),因此生成的命令是:
/bin/bash -c 'cd /path/to/project/api && export GEVENT_LOOP=pypycore.loop && /path/to/project/env/bin/gunicorn -c settings.py my-api:my_api'