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服务器无法重启问题

nginx uwsgi 和 cgi python 脚本

CentOS7 uwsgi重启(通过shell脚本获取进程号并kill)

django Nginx部署

nginx,uwsgi,DJango,502 当 DEBUG=False,“上游过早关闭连接”

关于Linux开机自动启动服务uwsgi. nginx。 我在/etc/rc.local中增加了