停止工作时重启Python.py

时间:2013-05-17 07:07:19

标签: python cherrypy gunicorn

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

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

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

4 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

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

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

CRON PART

*/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}')

然后我添加了这个函数,在从任何浏览器更新github之后通过cron OR重置cherrypy(假设我只知道{password})

重置网址为http://myserver.com/cp?reset= {密码}

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?

答案 2 :(得分:0)

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

  1. 实施os.pid()> /path/pid.file
  2. 创建连接到您的网络端口的服务脚本
  3. 尝试获取数据
  4. 如果没有收到任何数据,请终止PID @ / path / pid.file
  5. 重新启动脚本
  6. 你的主要剧本:

    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,并让你的操作系统在缺少PID的情况下启动你的脚本在/ path /中,Linux至少具有非常好的功能。

    最佳实践Ubuntu

    例如,使用系统service status apache2不仅仅是最佳实践,服务脚本还允许您重新加载,停止,启动,获取作业状态以及不使用哪些状态。

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

答案 3 :(得分:0)

也许您需要监督来监控您的枪支过程并在必要时重新启动它: