我正在使用 Cherrypy 框架在服务器上运行我的 python 代码。但是当负载增加时,该过程停止工作。
每次发生这种情况时,我都必须手动启动 python 代码。有什么办法可以将 Gunicorn 与 Cherrypy 一起使用,以便 Gunicorn 在停止工作时可以自动启动代码。
在这种情况下,任何其他解决方案也适用。只是想确保 python 程序不会停止工作。
Python 使用许多错误处理策略来控制流程。一个简单的try/except语句可能会引发异常,例如,如果您的内存溢出、负载增加或任何数量的问题导致您的代码停滞(没有实际代码很难看到)。
在 except 子句中,您可以清除分配的任何内存并再次重新启动进程。
我使用 cron 每隔几分钟检查一次内存负载,并在内存超过 500MB 时重置cherrypy——这样网络主机就不会通过电子邮件向我抱怨。当函数结束时,我的服务器上的某些东西不会释放内存,所以这是一个务实的解决方法。
这个 hack 可能很奇怪,因为我使用 HTTP 请求重置它,但那是因为我花了几个小时试图弄清楚如何使用 BASH 来做到这一点并放弃了。有用。
*/2 * * * * /usr/local/bin/python2.7 /home/{mypath}/cron_reset_cp.py > $HOME/cron.log 2>&1
#cron for resetting cherrypy /cp/ when 500+ MB
import os
#assuming starts in /home/my_username/
os.chdir('/home/my_username/cp/')
import mem
C = mem.MemoryMonitor('my_username') #this function adds up all the memory
memory = int(float(C.usage()))
if memory > 500:#MB
#### Tried: pid = os.getpid() #current process = cronjob --- THIS approach did not work for me.
import urllib2
cp = urllib2.urlopen('http://myserver.com/cp?reset={password}')
然后我添加了这个函数来通过cron重置cherrypy或者在任何浏览器更新github之后(假设只有我知道{password})
重置网址为http://myserver.com/cp?reset= {password}
def index(self, **kw):
if kw.get('reset') == '{password}':
cherrypy.engine.restart()
ip = cherrypy.request.headers["X-Forwarded-For"] #get_client_ip
return 'CherryPy RESETTING for duty, sir! requested by '+str(ip)
MemoryMonitor 部分来自这里: How to get current CPU and RAM usage in Python?
根据您的操作系统,尝试以下逻辑:
os.pid()
> /path/pid.file您的主要脚本:
import os
with open('./pidfile.pid', 'wb') as fh:
fh.write(str(os.getpid()))
... Execute your code as per normal ...
service.py 脚本:
from socket import *
from os import kill
s = socket()
try:
s.connect(('127.0.0.1', 80))
s.send('GET / HTTP/1.1\r\n\r\n')
len = len(s.recv(8192))
s.close()
except:
len = 0
if len <= 0:
with open('/path/to/pidfile.pid', 'rb') as fh:
kill(int(fh.read()))
并有一个 cronjob(在控制台中执行):
sudo export EDITOR=nano; crontab -e
现在您在文本编辑器中编辑您的 cronjobs,在底部写下以下两行:
*/2 * * * * cd /path/to/service.py; python service.py
*/5 * * * * cd /path/to/main/script.py; python script.py
Ctrl+X
当被要求保存更改时,请按和 ,Y
然后尽情享受。
另外,我建议不要从 service.py 脚本中重新启动脚本,而是建议 service.py 杀死 /path/pid.file 中的 PID,如果 /path 中缺少 PID,让您的操作系统处理启动脚本/,Linux 至少为此提供了非常漂亮的功能。
service status apache2
例如,使用系统不仅仅是被认为是最佳实践,服务脚本允许您重新加载、停止、启动、获取作业状态等等。
查看:http ://upstart.ubuntu.com/cookbook/#service-job 并检查所有其他应用程序的服务脚本,不仅将它们用作骨架,而且确保您的应用程序遵循相同的逻辑。
也许您需要 supervisord 来监控您的 gunicorn 进程并在必要时重新启动它: