经过近 2 天的工作,我终于解决了这个问题。我希望这个解决方案能帮助其他遇到类似问题的烧瓶/uwsgi 用户。
我有两个主要问题导致了这种情况。
1) 发现守护进程问题的最佳方法显然是日志文件和更简洁的结构。
sudo vim /etc/init/uwsgi.conf
将守护程序脚本更改为以下内容:
# file: /etc/init/uwsgi.conf
description "uWSGI server"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
exec /home/ubuntu/uwsgi-1.9.12/uwsgi -c /myproject/uwsgi.ini
vim /myproject/uwsgi.ini
[uwsgi]
socket = /tmp/uwsgi.sock
master = true
enable-threads = true
processes = 5
chdir= /myproject/F11/Engineering
module=F11:app
virtualenv = /myproject/myproject-env/
uid = www-data
gid = www-data
logto = /myproject/error.log
这是设置守护程序的更简洁的方法。还要注意最后一行如何设置日志文件。最初我将日志文件设置为/var/log/uwsgi/error.log。经过大量的汗水和泪水,我意识到守护进程以www-data 运行,因此无法访问/var/log/uwsgi/error.log,因为error.log 归root:root 所有。这使得 uwsgi 静默失败。
我发现将日志文件指向我自己的/myproject 效率更高,其中守护程序保证以www-data 访问。并且不要忘记让www-data 可以访问整个项目,否则守护程序将失败并显示Internal Server error message。 -->
sudo chown www-data:www-data -R /myproject/
重启uwsgi守护进程:
sudo service uwsgi restart
2) 现在您需要注意三个日志文件:
tail -f /var/log/upstart/uwsgi.log --> 在启动时显示您的守护进程存在问题
tail -f /var/log/nginx/error.log --> 当 wsgi 访问被拒绝时显示权限问题,通常是因为 /tmp/uwsgi.sock 文件归 root 而不是 www-data 所有。在这种情况下,只需删除 sock 文件 sudo rm /tmp/uwsgi.sock
tail -f /myproject/error.log --> 显示应用程序中 uwsgi 抛出的错误
这种日志文件组合帮助我发现在我的 Flask 应用程序中使用 Flask-Babel 进行了错误的导入。从这个意义上说很糟糕,我使用库的方式是回退到系统的语言环境来确定日期时间格式。
File "/myproject/F11/Engineering/f11_app/templates/show_records.html", line 25, in block "body"
<td>{{ record.record_date|format_date }}</td>
File "./f11_app/filters.py", line 7, in format_date
day = babel_dates.format_date(value, "EE")
File "/myproject/myproject-env/local/lib/python2.7/site-packages/babel/dates.py", line 459, in format_date
return pattern.apply(date, locale)
File "/myproject/myproject-env/local/lib/python2.7/site-packages/babel/dates.py", line 702, in apply
return self % DateTimeFormat(datetime, locale)
File "/myproject/myproject-env/local/lib/python2.7/site-packages/babel/dates.py", line 699, in __mod__
return self.format % other
File "/myproject/myproject-env/local/lib/python2.7/site-packages/babel/dates.py", line 734, in __getitem__
return self.format_weekday(char, num)
File "/myproject/myproject-env/local/lib/python2.7/site-packages/babel/dates.py", line 821, in format_weekday
return get_day_names(width, context, self.locale)[weekday]
File "/myproject/myproject-env/local/lib/python2.7/site-packages/babel/dates.py", line 69, in get_day_names
return Locale.parse(locale).days[context][width]
AttributeError: 'NoneType' object has no attribute 'days'
这是我使用 Flask 过滤器的方式:
import babel.dates as babel_dates
@app.template_filter('format_date')
def format_date(value):
day = babel_dates.format_date(value, "EE")
return '{0} {1}'.format(day.upper(), affix(value.day))
最奇怪的是,这段代码在开发环境中运行良好(!)。从命令行将 uwsgi 作为 root 进程运行时,它甚至可以正常工作。但是当由 www-data 守护进程运行时它会失败。这一定与语言环境的设置方式有关,而 Flask-Babel 正试图回退到该语言环境。
当我像这样更改导入时,它终于与守护进程一起工作了:
from flask.ext.babel import format_date
@app.template_filter('format_date1')
def format_date1(value):
day = format_date(value, "EE")
return '{0} {1}'.format(day.upper(), affix(value.day))
因此,在使用 Eclipse/Aptana Studio 时要小心,因为它试图为代码中的类选择正确的命名空间。真的会变丑。
自从 2 天以来,它现在作为 Amazon Ec2 (Ubuntu 12.04) 上的 uwsgi 守护程序工作得非常好。我希望这个经验可以帮助到 Python 开发者。