uwsgi 关闭/重启 夯死问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uwsgi 关闭/重启 夯死问题相关的知识,希望对你有一定的参考价值。
参考技术A 近期使用uwsgi启动django服务,发现在stop/reload uwsgi时会出现hangs问题,具体日志表现为:在测试中发现无论用什么防线先uwsgi发送stop/reload信号,uwsgi都会进入一种假死状态,即不接收请求,也不结束进程。
期初以为uwsgi进程是在处理未完成的web请求。后来发现在没有任何请求时,uwsgi也会进入这种夯死状态。
首先说明问题的原因是因何而起。
出现这种夯死的问题是由于在uwsgi中使用了线程导致。
这里创建了一个最简单的django服务,并用uwsgi来启动。
首先,配置uwsgi为进程模式启动,这里创建了5个进程。
uwsgi配置文件如下:
现在来reload uwsgi服务,并查看uwsgi的日志。
结论:在uwsgi使用进程模式时,reload uwsgi不会出现夯死的问题。
前面以进程方式启动uwsgi没有出现夯死问题,那么现在就试一下以线程模式启动wusgi。这里启动了5个进程,每个进程中又包含了两个线程。
uwsgi配置文件如下:
reload uwsgi服务,并观察日志输出。
结论:在uwsgi中使用线程模式也不会造成reload夯死的问题。
uwsgi的线程不会造成任何问题,那前文所指的线程究竟是什么?
现在uwsgi启动脚本中创建一个线程,在这种情况下尝试reload uwsgi并查看日志输出。
随后以线程方式启动uwsgi,并reload uwsgi。
结论:在uwsgi app中使用线程就导致reload夯死。
若场景中非要在uwsgi app中使用线程,可以通过配置 reload-mercy 和 worker-reload-mercy 两个参数避免夯死的问题。
uwsgi配置文件如下:
再次reload uwsgi服务,输出日志如下:
这里虽然也会出现NO MERCY问题,但是uwsgi在reload过程中并没有出现夯死的情况。
错误:从上游 [uWSGI/Django/NGINX] 读取响应标头时,上游过早关闭连接
【中文标题】错误:从上游 [uWSGI/Django/NGINX] 读取响应标头时,上游过早关闭连接【英文标题】:Error: upstream prematurely closed connection while reading response header from upstream [uWSGI/Django/NGINX] 【发布时间】:2014-04-02 04:43:30 【问题描述】:我目前总是在我的用户正在执行的查询中得到 502...通常返回 872 行并且需要 2.07 才能在 MySQL 中运行。然而,它返回了很多信息。 (每一行包含很多东西)。有什么想法吗?
运行 Django (tastypie Rest API)、Nginx 和 uWSGI 堆栈。
使用 NGINX 配置服务器
# the upstream component nginx needs to connect to
upstream django
server unix:///srv/www/poka/app/poka/nginx/poka.sock; # for a file socket
# configuration of the server
server
# the port your site will be served on
listen 443;
# the domain name it will serve for
server_name xxxx; # substitute your machine's IP address or FQDN
charset utf-8;
# max upload size
client_max_body_size 750M; # adjust to taste
# Finally, send all non-media requests to the Django server.
location /
uwsgi_pass django;
include /srv/www/poka/app/poka/nginx/uwsgi_params; # the uwsgi_params file you installed
UWSGI 配置
# process-related settings
# master
master = true
# maximum number of worker processes
processes = 2
# the socket (use the full path to be safe
socket = /srv/www/poka/app/poka/nginx/poka.sock
# ... with appropriate permissions - may be needed
chmod-socket = 666
# clear environment on exit
vacuum = true
pidfile = /tmp/project-master.pid # create a pidfile
harakiri = 120 # respawn processes taking more than 20 seconds
max-requests = 5000 # respawn processes after serving 5000 requests
daemonize = /var/log/uwsgi/poka.log # background the process & log
log-maxsize = 10000000
#http://uwsgi-docs.readthedocs.org/en/latest/Options.html#post-buffering
post-buffering=1
logto = /var/log/uwsgi/poka.log # background the process & log
【问题讨论】:
显而易见的答案是拆分数据或增加超时。那不行吗? 在哪里可以增加超时时间?增加harakiri并没有帮助......我需要在不久的将来实际拆分数据......但我现在没有时间...... 我假设 2.07 是秒?日志中有任何内容吗?直接运行uWSGI HTTP server,看看是uWSGI还是nginx卡住了? 是的,在几秒钟内......但问题是 872 行现在不算什么......在不久的将来它可能会增长到 10,000。但用户最终需要以一种或另一种方式将这 10,000 行数据输入到他的 iPad 中。我应该开始考虑批量发送数据吗? 【参考方案1】:这可能是 uwsgi 配置问题,而不是 Nginx。我看到您有 uwsgi processes = 2 和 harakiri = 120,您是否尝试过一一更改这些以及其他字段?
我遇到了同样的问题,但不是我的 NGINX 配置,而是我的 UWSGI 进程在我将 JSON 从客户端发布到服务器时导致超时错误。我的进程为 5,我将其更改为 1,它解决了这个问题。对于我的应用程序,我只需要一次运行 1 个进程。
这是解决超时问题和 502 网关问题(上游过早关闭)的有效 UWSGI 配置自动引导 ini 文件。
autoboot.ini
#!/bin/bash
[uwsgi]
socket = /tmp/app.sock
master = true
chmod-socket = 660
module = app.wsgi
chdir = home/app
close-on-exec = true # Allow linux shell via uWSGI
processes = 1
threads = 2
vacuum = true
die-on-term = true
希望对你有帮助。
【讨论】:
【参考方案2】:有时可能是权限问题。检查项目目录的权限。
【讨论】:
【参考方案3】:我遇到了同样的问题,为我解决的问题是将我的域添加到 settings.py 例如:
ALLOWED_HOSTS = ['.mydomain.com', '127.0.0.1', 'localhost']
同样的问题,我的意思是我什至无法加载页面,nginx 会返回 502 而不提供任何可能导致应用程序崩溃的页面。
而 nginx 日志包含:
Error: upstream prematurely closed connection while reading response header from upstream
【讨论】:
【参考方案4】:在您的@django 位置块中,您可以尝试添加一些代理读取和连接超时属性。例如
location @django
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_redirect off;
# proxy header definitions
...
proxy_pass http://django;
【讨论】:
前 3 行帮助我解决了 502 ws 错误【参考方案5】:这不太可能是 nginx 配置问题。
几乎可以肯定,后端实际上正在崩溃(或只是终止连接),而不是给出格式错误的响应。即错误消息告诉您问题是什么,但您正在寻找错误的地方来解决它。
您没有提供足够的信息来确定确切的问题是什么,但如果我不得不猜测:
通常返回 872 行并在 MySQL 中运行需要 2.07。然而,它返回了很多信息。
它要么在某个地方超时,要么内存不足。
【讨论】:
872 行现在不算什么...在不久的将来它可能会增长到 10,000。但用户最终需要以一种或另一种方式将这 10,000 行输入到他的 iPad 中。我应该开始考虑批量发送数据吗? 不,你应该找到导致后端终止请求的原因。 支持您的内存不足。我认为短期内很难意识到内存可能是此类错误流的问题。以上是关于uwsgi 关闭/重启 夯死问题的主要内容,如果未能解决你的问题,请参考以下文章
使用uwsgi部署,主机重启之后,uwsgi服务器无法重启问题
CentOS7 uwsgi重启(通过shell脚本获取进程号并kill)