nginx+uwsgi+django报502错误分析

时间:2022-12-14 20:05:44

摘要:nginx+uwsgi+django报502错误
nginx :

upstream prematurely closed connection while reading response header from upstream

uwsgi :

Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/Django-1.8.4-py2.7.egg/django/core/handlers/wsgi.py", line 170, in __call__
self.load_middleware()
File "/usr/local/lib/python2.7/dist-packages/Django-1.8.4-py2.7.egg/django/core/handlers/base.py", line 50, in load_middleware
mw_class = import_string(middleware_path)
File "/usr/local/lib/python2.7/dist-packages/Django-1.8.4-py2.7.egg/django/utils/module_loading.py", line 26, in import_string
module = import_module(module_path)
File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
__import__(name)
ImportError: No module named transaction

nginx+uwsgi+django报502错误分析

项目框架

项目使用的是nginx+uwsgi+django来做web项目框架

the web client <-> the web server(nginx) <-> the socket <-> uWSGI <-> Django

项目环境安装请看

http://blog.csdn.net/libing1991_/article/details/47947103
http://blog.csdn.net/libing1991_/article/details/47971965

项目部署问题

环境信息:
ubuntu : 14.04 LTS
nginx : 1.8.0
uwsgi : 2.0.6
Django : 1.8.4
项目访问:https://localhost:443
浏览器显示:502 bad gateway 并输出nginx版本信息

问题解决

问题排查

根据uwsgi-docs.pdf依次排查nginx,uwsgi,django安装及部署问题,结果均显示正常,无安装错误
uwsgi-docs.pdf可以到官网下载,里面提供了详细的操作步骤
https://www.baidu.com/link?url=v8cJ2Z1wLaZgb6F2cGTs97d19wGZkGlEXdJnATwX3FmMgh_CTtSzZbFrcCND85on_Qiz1kr-kajIaqOLh91iLq&wd=&eqid=98394c6600003b250000000255dfcf68
然后就可是上网查找关于nginx报502的问题
相关答案汇总:
- 502 报错主要是由于服务器端产生错误导致,而nginx主要是做请求代理,而在问题排查时已经确认nginx安装及测试成功,所以问题出自uwsgi
或者Django
- uwsgi是通过socket与nginx进行通信,查看网络好的配置,均无效,仍然是502,放弃
- Django排查,单独创建项目,通过nginx+uwsgi访问,成功
- 最后只能硬着头皮查了日志,这个框架是头一次学习,所以花了将近3天左右才意识到通过日志去解决问题
注:问题排查从日志着手很重要

日志信息

通过项目的log输出路径查看对应的日志信息

nginx:error log (部分)

2015/08/26 23:29:06 [error] 2427#0: *10 upstream prematurely closed connection while reading response header from upstream, client: 127.0.0.1, server: 127.0.0.1, request: "GET /images/add.gif HTTP/1.1", upstream: "uwsgi://127.0.0.1:8090", host: "localhost"
2015/08/26 23:29:06 [error] 2427#0: *10 upstream prematurely closed connection while reading response header from upstream, client: 127.0.0.1, server: 127.0.0.1, request: "GET /images/add.gif HTTP/1.1", upstream: "uwsgi://127.0.0.1:8090", host: "localhost"
2015/08/26 23:29:07 [error] 2427#0: *10 upstream prematurely closed connection while reading response header from upstream, client: 127.0.0.1, server: 127.0.0.1, request: "GET /favicon.ico HTTP/1.1", upstream: "uwsgi://127.0.0.1:8090", host: "localhost"
2015/08/26 23:29:07 [error] 2427#0: *10 upstream prematurely closed connection while reading response header from upstream, client: 127.0.0.1, server: 127.0.0.1, request: "GET /favicon.ico HTTP/1.1", upstream: "uwsgi://127.0.0.1:8090", host: "localhost"

nginx:access log (部分)

127.0.0.1 - - [26/Aug/2015:23:29:06 +0800] "GET /images/add.gif HTTP/1.1" 502 172 "-" "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:40.0) Gecko/20100101 Firefox/40.0"
127.0.0.1 - - [26/Aug/2015:23:29:07 +0800] "GET /favicon.ico HTTP/1.1" 502 172 "-" "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:40.0) Gecko/20100101 Firefox/40.0"

uwsgi(部分)

[pid: 1086|app: 0|req: 4/8] 127.0.0.1 () {40 vars in 651 bytes} [Wed Aug 26 23:29:06 2015] GET /images/add.gif => generated 0 bytes in 0 msecs (HTTP/1.1 500) 0 headers in 0 bytes (0 switches on core 0)
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/Django-1.8.4-py2.7.egg/django/core/handlers/wsgi.py", line 170, in __call__
self.load_middleware()
File "/usr/local/lib/python2.7/dist-packages/Django-1.8.4-py2.7.egg/django/core/handlers/base.py", line 50, in load_middleware
mw_class = import_string(middleware_path)
File "/usr/local/lib/python2.7/dist-packages/Django-1.8.4-py2.7.egg/django/utils/module_loading.py", line 26, in import_string
module = import_module(module_path)
File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
__import__(name)
ImportError: No module named transaction
[pid: 1086|app: 0|req: 5/9] 127.0.0.1 () {40 vars in 651 bytes} [Wed Aug 26 23:29:07 2015] GET /favicon.ico => generated 0 bytes in 0 msecs (HTTP/1.1 500) 0 headers in 0 bytes (0 switches on core 0)
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/Django-1.8.4-py2.7.egg/django/core/handlers/wsgi.py", line 170, in __call__
self.load_middleware()
File "/usr/local/lib/python2.7/dist-packages/Django-1.8.4-py2.7.egg/django/core/handlers/base.py", line 50, in load_middleware
mw_class = import_string(middleware_path)
File "/usr/local/lib/python2.7/dist-packages/Django-1.8.4-py2.7.egg/django/utils/module_loading.py", line 26, in import_string
module = import_module(module_path)
File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
__import__(name)
ImportError: No module named transaction

日志分析

在问题排查时,已经确定不是由nginx引起的问题,所以就把问题聚焦在uwsgi日志上。nginx日志提示uwsgi过早的释放了socket连接,而过早释放连接主要是出在这句代码中:查看错误堆栈

File "/usr/local/lib/python2.7/dist-packages/Django-1.8.4-py2.7.egg/django/core/handlers/wsgi.py", line 170, in __call__
self.load_middleware()

根据这个错误,找到了对应文件wsgi.py,查看第170行
nginx+uwsgi+django报502错误分析
通过代码看出,报错是由于项目在加载中间件时,出现错误,未发现transaction这个事务处理中间件。
Django中间件:是在有些场合,需要对Django处理的每个request都执行某段代码。 这类代码可能是在view处理之前修改传入的request,或者记录日志信息以便于调试,等等。这类功能可以用Django的中间件框架来实现,该框架由切入到Django的request/response处理过程中的钩子集合组成。 这个轻量级低层次的plug-in系统,能用于全面的修改Django的输入和输出。

问题发现了,项目在加载中间件时,项目中没有对应的中间件,所以上网搜索对应的中间件配置,中间件配置在项目目录下的settings.py文件中:
nginx+uwsgi+django报502错误分析
可以看出项目中确实配置了事务处理中间件
‘django.middleware.transaction.TransactionMiddleware’
然后去对应的目录下查找是否有该中间件

/usr/local/lib/python2.7/dist-packages/Django-1.8.4-py2.7.egg/django/middleware

确实没有,然后试着把这个中间件引掉,重新部署,发现Django报错,原因是代码中使用了这个中间件进行请求处理。
想了很久,不知道怎么办,最后再Django群里提了这个问题,有位大神给了我提示:
nginx+uwsgi+django报502错误分析
Django 文档提示,1.8之后已经移除了transaction事务处理中间件
最后问题为版本问题。
最后将Django版本换成1.7.10版本,问题成功解决。

通过这个解决这个问题,得出:
1. 解决问题要从日志信息中入手,简单,直接,网上搜索,向大神提问都不靠谱
2. 关于项目部署,软件版本很重要,对每个软件版本的更新要及时关注,了解版本变化
3. django的版本更新没有java好,jdk更新后原有的API保留一段时间,通过deprecate注解提示用户,后期的版本已经移除该API,不推荐使用,而不是直接删除,直接删除将引起早期项目无法部署,要重新修改等问题。