关于python:如何避免Django子线程被uWSGI respawn杀死

How to avoid Django sub thread being killed by uWSGI respawn

我由Django uWSGI创建了一个Web服务器。基本流程是:收到请求后,Django将通过python内置库" Threading"启动子线程以异步编写db,并在主线程中立即将其返回给客户端。

如何,uWSGI有时会重新生成工作进程(也许当进程没有处理请求时?),这导致后台子线程也被杀死,即使尚未完成。有什么线索可以避免uWSGI不重新生成具有正在运行的子线程的工作进程?

uWSGI重生日志:

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

uWSGI ini config(版本2.0.12):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[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版)应用程序伪代码:

在handlers.py中的

1
2
3
4
5
6
7
8
9
10
11
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()

in views.py:

1
2
3
4
5
from handlers import myHandler

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


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

您应该使用像Celery这样的脱机工作系统。


在我的情况下,此问题是由于数据库的某些操作延迟所致。

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

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

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

规则:

定义流程的数量(production.ini或等效版本中的processs参数)

1
2
3
4
q=n*2

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

确定螺纹的数量(production.ini或同等产品中的threads参数)

1
2
3
4
5
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,从而导致"锁定",请在[uwsgi]部分中添加" lazy-apps = true"参数。仅当您的系统开始出现问题时,才执行此操作。