1

我正在使用 Cherrypy 框架在服务器上运行我的 python 代码。但是当负载增加时,该过程停止工作。

每次发生这种情况时,我都必须手动启动 python 代码。有什么办法可以将 Gunicorn 与 Cherrypy 一起使用,以便 Gunicorn 在停止工作时可以自动启动代码。

在这种情况下,任何其他解决方案也适用。只是想确保 python 程序不会停止工作。

4

4 回答 4

1

Python 使用许多错误处理策略来控制流程。一个简单的try/except语句可能会引发异常,例如,如果您的内存溢出、负载增加或任何数量的问题导致您的代码停滞(没有实际代码很难看到)。

在 except 子句中,您可以清除分配的任何内存并再次重新启动进程。

于 2013-05-17T07:17:56.920 回答
1

我使用 cron 每隔几分钟检查一次内存负载,并在内存超过 500MB 时重置cherrypy——这样网络主机就不会通过电子邮件向我抱怨。当函数结束时,我的服务器上的某些东西不会释放内存,所以这是一个务实的解决方法。

这个 hack 可能很奇怪,因为我使用 HTTP 请求重置它,但那是因为我花了几个小时试图弄清楚如何使用 BASH 来做到这一点并放弃了。有用。

CRON 部分

*/2 * * * * /usr/local/bin/python2.7 /home/{mypath}/cron_reset_cp.py > $HOME/cron.log 2>&1

以及 cron_reset_cp.py 中的代码...

#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?

于 2013-05-18T14:23:31.313 回答
0

根据您的操作系统,尝试以下逻辑:

  1. 实现一个os.pid()> /path/pid.file
  2. 创建连接到您的网络端口的服务脚本
  3. 尝试获取数据
  4. 如果未收到任何数据,则终止 PID @/path/pid.file
  5. 重启脚本

您的主要脚本:

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 至少为此提供了非常漂亮的功能。

最佳实践 Ubuntu

service status apache2例如,使用系统不仅仅是被认为是最佳实践,服务脚本允许您重新加载、停止、启动、获取作业状态等等。

查看:http ://upstart.ubuntu.com/cookbook/#service-job 并检查所有其他应用程序的服务脚本,不仅将它们用作骨架,而且确保您的应用程序遵循相同的逻辑。

于 2013-05-17T07:18:42.553 回答
0

也许您需要 supervisord 来监控您的 gunicorn 进程并在必要时重新启动它:

于 2013-05-17T09:46:44.113 回答