解决 Django + Gunicorn + Nginx 的 ”upstream prematurely closed connection while reading response“ 问题

背景:一个应用,使用 Django 开发。部署到生产环境,使用 Gunicorn 运行 Django 应用,使用 Nginx 做为前端入口。使用 Supervisor 控制 Gunicorn 服务。

现象

  • 在线生成一个报告,等待下载时,出现“后台出错“。
  • 在本地调试环境下,相同的代码,能报告能正常重生成并下载。

日志

从 Django 的应用后台日志,看不到任何问题。但是从 Nginx 的 access_error.log 可以看到以下错误:

*196220 upstream prematurely closed connection while reading response header from upstream, client: x.x.x., server: xxx.xxx.com, request: "POST /some_url_path/?keyword=some_keyword HTTP/1.1",

另外,从 gunicorn 的 log 可以看到以下错误:

[2022-12-31 10:14:18 +0800] [28748] [CRITICAL] WORKER TIMEOUT (pid:28760)

第一次尝试,修改 nginx 的 proxy 超时配置

先怀疑是不是 Nginx 超时了。
在 Nginx 的代理到后台 app 的配置中,增加以下 timeout 相关的内容:

location / {
	proxy_pass http://app;      # <-- defined in previous lines
	proxy_connect_timeout 360s;  # <-- newly added
	proxy_read_timeout 360s;     # <-- newly added
}	

但是,修改了 Nginx 配置后,还是不管用。Nignx 日志和 Gunicorn 日志中,同样的错误仍然存在。

第二次尝试,修改 Supervisor 中,Gunicorn 的超时配置

再理解一下 Nginx 的信息 - 是 Upstream 关闭了连接。也就是说,应该是 Gunicorn 服务主动关闭了连接。
于是查 Gunicorn 相关的参数,原来 Gunicorn 的缺省 timeout 时间是 30秒。因此,尝试修改 Supervisor 中 Gunicorn 的 Timeout 配置。原来的 SuperVisor 配置:

command = gunicorn app.wsgi.application -b 127.0.0.1:xxxx(port) -w 1 --log-level=debug --log-file=/var/log/gunicorn/app.log

新增关于 timeout 的配置

command = gunicorn app.wsgi.application -b 127.0.0.1:xxxx(port) -w 1 --timeout=300 --graceful-timeout=60 --log-level=debug --log-file=/var/log/gunicorn/app.log

然后要重启 Supervisor 服务。!!注意,必须重启 Supervisor服务才能使配置修改生效 !!

sudo systemctl restart supervisor

如果仅仅是使用 supervisorctl 来重启 gunicorn 这个应用是不行的。

总结

最终,第二次尝试,问题解决。
可以看到,这是 Gunicorn 网关的超时错误,增加 Gunicorn Worker 的超时时间,即可解决。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值