Nginx + Gunicorn + Flask --> 使用 X 小时后常有 500 个错误
Nginx + Gunicorn + Flask --> constant 500 errors after X hours of usage
我有一个 Flask 应用 运行 Nginx + Gunicorn 通常没有问题。该应用程序仍在开发中,因此目前每小时大约只有一个请求。
问题是 Gunicorn 似乎总是在上次重启后大约 12-36 小时后突然崩溃。发生这种情况时,nginx 仍然可以提供静态文件,但是任何需要 Gunicorn 的东西都会开始 return 500 错误,即使 Gunicorn 进程仍在服务器上 运行。在接下来的 12-36 小时内,通过 sudo supervisorctl restart xxx
重新启动 Gunicorn(不需要重新启动 nginx),问题总是得到解决。到目前为止,该问题已发生约 10 次。是否有可能以某种方式改进日志记录或做其他事情?
Nginx 配置文件 (/etc/nginx/sites-available/xxx_gunicorn):
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
access_log /var/log/nginx/xxx-access.log;
server_name 127.0.0.1 www.xxx.yy;
location / {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_connect_timeout 10;
proxy_read_timeout 10;
proxy_pass http://127.0.0.1:8000/;
}
location /static {
alias /opt/xxx/static/;
}
}
supervisor conf 启动 gunicorn (/etc/supervisor/conf.d/xxx.conf)
[program:xxx]
command = gunicorn xxx:app -b localhost:8000 --debug --log-level debug --log-file /var/log/gunicorn.log --error-logfile /var/log/gunicorn.error.log --workers 2 --worker-connections 1000 --max-requests 100 --timeout 30
directory = /opt/xxx
user = ubuntu
stdout_logfile = /var/log/gunicorn.log ; Where to write log messages
autostart=true
autorestart=true
redirect_stderr=true
xxx.py
...
app = Flask(__name__)
...
if __name__ == '__main__':
app.debug=True
app.run()
/var/log/gunicorn.error.log :500 错误开始时没有记录任何内容。 500错误之前也没有可疑行。
/var/log/gunicorn.log : 没有可疑行。
/var/log/nginx/error.log : 没有可疑行。
/var/log/nginx/xxx-access.log :此处显示 500 个错误:
80.221.255.134 - - [27/Jan/2015:07:01:50 +0000] "GET / HTTP/1.1" 500 291 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36"
据我所知,gunicorn 没有选项 log-file,只有 access-logfile 和 error-logfile :
http://gunicorn-docs.readthedocs.org/en/latest/settings.html#logging
但是要在 Flask 应用程序中记录错误,您必须在其中设置 python 记录器。比如可以这样写:
from logging.handlers import WatchedFileHandler
@app.before_first_request
def setup_logging():
"""
Setup logging
"""
handler = WatchedFileHandler("/var/log/your_flask_app.log")
app.logger.addHandler(handler)
app.logger.setLevel(logging.INFO)
我有一个 Flask 应用 运行 Nginx + Gunicorn 通常没有问题。该应用程序仍在开发中,因此目前每小时大约只有一个请求。
问题是 Gunicorn 似乎总是在上次重启后大约 12-36 小时后突然崩溃。发生这种情况时,nginx 仍然可以提供静态文件,但是任何需要 Gunicorn 的东西都会开始 return 500 错误,即使 Gunicorn 进程仍在服务器上 运行。在接下来的 12-36 小时内,通过 sudo supervisorctl restart xxx
重新启动 Gunicorn(不需要重新启动 nginx),问题总是得到解决。到目前为止,该问题已发生约 10 次。是否有可能以某种方式改进日志记录或做其他事情?
Nginx 配置文件 (/etc/nginx/sites-available/xxx_gunicorn):
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
access_log /var/log/nginx/xxx-access.log;
server_name 127.0.0.1 www.xxx.yy;
location / {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_connect_timeout 10;
proxy_read_timeout 10;
proxy_pass http://127.0.0.1:8000/;
}
location /static {
alias /opt/xxx/static/;
}
}
supervisor conf 启动 gunicorn (/etc/supervisor/conf.d/xxx.conf)
[program:xxx]
command = gunicorn xxx:app -b localhost:8000 --debug --log-level debug --log-file /var/log/gunicorn.log --error-logfile /var/log/gunicorn.error.log --workers 2 --worker-connections 1000 --max-requests 100 --timeout 30
directory = /opt/xxx
user = ubuntu
stdout_logfile = /var/log/gunicorn.log ; Where to write log messages
autostart=true
autorestart=true
redirect_stderr=true
xxx.py
...
app = Flask(__name__)
...
if __name__ == '__main__':
app.debug=True
app.run()
/var/log/gunicorn.error.log :500 错误开始时没有记录任何内容。 500错误之前也没有可疑行。
/var/log/gunicorn.log : 没有可疑行。
/var/log/nginx/error.log : 没有可疑行。
/var/log/nginx/xxx-access.log :此处显示 500 个错误:
80.221.255.134 - - [27/Jan/2015:07:01:50 +0000] "GET / HTTP/1.1" 500 291 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36"
据我所知,gunicorn 没有选项 log-file,只有 access-logfile 和 error-logfile :
http://gunicorn-docs.readthedocs.org/en/latest/settings.html#logging
但是要在 Flask 应用程序中记录错误,您必须在其中设置 python 记录器。比如可以这样写:
from logging.handlers import WatchedFileHandler
@app.before_first_request
def setup_logging():
"""
Setup logging
"""
handler = WatchedFileHandler("/var/log/your_flask_app.log")
app.logger.addHandler(handler)
app.logger.setLevel(logging.INFO)