如何避免由uWSGI respawn杀死Django子线程

时间:2016-11-14 13:17:21

标签: python django multithreading uwsgi

我通过Django + uWSGI创建了一个Web服务器。基本流程是:当收到请求时,Django将通过python内置库发起一个子线程"线程"异步写入db,在主线程中它会立即响应客户端。

如何,uWSGI有时会重新生成工作进程(可能在进程没有请求处理的情况下?),这导致后台子线程也被杀死,即使它还没有完成。是否有任何线索可以避免uWSGI重新生成具有正在运行的子线程的工作进程?

uWSGI重生日志:

DAMN ! worker 4 (pid: 31161) died, killed by signal 9 :( trying respawn ...

uWSGI ini config(版本2.0.12):

[uwsgi]
# Django's wsgi file
wsgi-file   = /home/fh/dj_uwsgi/dj_site/dj_site/wsgi.py    
master      = true
processes   = 10
http       = :8001
threads = 2
enable-threads = true
http-timeout = 10     
max-requests = 5000        
chmod-socket    = 664
vacuum      = true    
pidfile = /home/fh/dj_uwsgi/dj_site/uwsgi.pid
daemonize = /home/fh/log/uwsgi_dj.log

Django(版本1.8)app伪代码:

在handlers.py中:

import threading

class SubThreadClass(threading.Thread):
    daemon = True

    def run(self):
        # actions to write db

def myHandler():
    my_sub_thread = SubThreadClass()
    my_sub_thread.start()
在views.py中

from handlers import myHandler

def url_handler(request): 
    myHandler()
    return HttpResponse()

2 个答案:

答案 0 :(得分:1)

在您不管理的环境中,手动处理线程很少是个好主意。

您应该使用Celery等离线工作人员系统。

答案 1 :(得分:0)

在我的情况下,这个问题是由于我的数据库的某些操作延迟造成的。

我将 uWSGI 金字塔http://docs.pylonsproject.org/projects/pyramid/en/latest/)一起使用。由于您使用的是Django(Python),因此该解决方案很可能对您有用。

下面引用的设置位于配置文件 production.ini [uwsgi] 部分)(http://uwsgi-docs.readthedocs.io/en/latest/Options.html)。

我"解决了#34;使用以下规则的这个问题。那规则"解决"这个问题大大减少了它的发生。到目前为止,我还没有看到任何完全避免它的东西。我的性能也有所提高(需要测试,但我们认为这是一个很好的改进)。解决方案基本上是根据数据库允许的连接数增加线程数(您还可以增加数据库允许的连接数)。

<强>规则:

定义流程&QUANTITY(您的produ.ini中的进程参数或等效项目)

q=n*2

q - number of processes
n - number of CPUs/cores

定义线程数量(您的produ.ini或同等产品中的线程参数)

t=(p*0.8)/q

t - number of threads
p - number of connections available in your database
q - number of processes

另请注意, sqlalchemy.pool_size 参数(如果使用sqlalchemy http://www.sqlalchemy.org/)应与t具有相同的值。

<强>加:

防止Python进程在重新启动时同时访问您的production.ini,从而导致&#34;锁定&#34;添加&#34; lazy-apps = true&#34; [uwsgi]部分中的参数。 仅在系统出现问题时执行此操作。