uwsgi+nginx 出现readv() failed (104: Connection reset by peer)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uwsgi+nginx 出现readv() failed (104: Connection reset by peer)相关的知识,希望对你有一定的参考价值。
参考技术A 部署的环境是nginx+uwsgi+django项目,当前端页面发送post请求时,有一定的概率出现ERR_CONTENT_LENGTH_MISMATCH错误,查看日志发现django项目已经成功执行,并且返回了rest api的请求,没有报错。报错的地方在nginx,显示 readv() failed (104: Connection reset by peer) while reading upstream, 错误。查看了网上的解决方法,大部分都是php+nginx的部署。总体的解决思路都是调大buffer。这里我们的调整方式是,调整uwsgi配置文件里面的buffer。添加下面两行,我的问题就解决了。
uWSGI 踩坑记
一、协议的一致性
uWSGI 是在 nginx 后面,所以 nginx 转发请求时的协议要和 uWSGI 监听的协议一致。否则就会出现问题,因为是三者之间的通信,排查起来需要想清楚请求传递的次序:
Nginx -> uWSGI -> app
1.1 uWSGI 异常信息
invalid request block size: 21573 (max 4096)...skip
如果按照下面的配置就会出现上述的异常:
# Nginx 配置
location / {
proxy_pass http://127.0.0.1:6000;
}
# 搭配 uWSGI 配置
uwsgi --socket :6000 --wsgi-file app.py
1.2 Nginx 异常信息
upstream prematurely closed connection while reading response header from upstream, client: 120.xxx.xxx.xxx, server: hellogithub.com, request: "GET / HTTP/1.1", upstream: "uwsgi://127.0.0.1:6000", host: "hellogithub.com"
原因是:nginx 为 uwsgi 协议,uWSGI 为 http 协议,那么请求会到不了 uWSGI。
1.3 正确配置示例:
1.通过 uwsgi 协议传递请求
# Nginx 配置
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:6000;
}
# 搭配 uWSGI 配置
uwsgi --socket :6000 --wsgi-file app.py
上述配置的的意思是说 “把每个请求传递到服务器绑定的端口 6000,并且使用 uwsgi 协议通信”。
2.通过 http 协议传递请求(不推荐)
# Nginx 配置
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:6000;
}
# 搭配 uWSGI 配置
uwsgi --http :6000 --wsgi-file app.py
每个请求通过 http 协议传递给 6000端口的服务,但是服务应用想要获得请求的真实 IP 和请求的 http 信息需要在 nginx 中额外配置。
二、配置参数
2.1 指定配置文件启动时
1.切记配置文件中要有 pidfile 参数
pidfile=/tmp/myproject-master.pid
否则 supervisor 重启 uWSGI 不会关闭进程,而且为不报错。
TODO这样可能会导致另外一个异常,我现在如果使用指定 ini 文件启动就会报这个问题,后面查到原因再来写:
robably another instance of uWSGI is running on the same address (:6000).
bind(): Address already in use [core/socket.c line 769]
2.2 启动 gevent
uwsgi --gevent 100 --gevent-monkey-patch --http :9090 -M --processes 4 --wsgi-file wsgi.py
增加 --gevent-monkey-patch
参数可以不用修改代码就采用 gevent 方式启动。
2.3 环境变量
supervisor 配置的环境变量不会传递给uWSGI启动的服务。举个例子:
## supervisor 配置
environmenit=name=hellogithub
## app 代码片段
pro_name = os.getenv(‘name‘)
这时 pro_name
会返回 None
而不是预期的 hellogithub
,所以启动 uWSGI 时需要增加环境变量参数:--env name=hellogithub
,如此可达到预期。
三、参考
以上是关于uwsgi+nginx 出现readv() failed (104: Connection reset by peer)的主要内容,如果未能解决你的问题,请参考以下文章
在配置nginx和uwsgi时,出现 "没有这样的文件或目录 "的错误。
记录一下在ubuntu 上配置nginx+uwsgi+flask出现的一点问题.
django+uwsgi+nginx部署访问出现问题(无法解决寻求帮助)
uwsgi部署到nginx出现invalid request block size: 4161 (max 4096)...skip问题