首先,本文的mysite是指自己的站点名称。
安装nginx
apt-get install nginx
关闭nginx默认的log
vi /etc/nginx/nginx.conf
找到以下access_log和error_log,修改为null。
access_log /dev/null;
error_log /dev/null;
接下来配置站点配置,进入nginx站点配置目录,并新建配置文件
cd /etc/nginx/sites-available/
vi mysite
写入一下对应站点配置文本,并保存
server {
listen 80;
server_name www.mysite.com mysite.com;
#修改最大上传为10M,默认为2M,超出大小出现413 Request Entity Too Large错误
client_max_body_size 10M;
#一定要记得在网站目录下创建logs文件夹,不然会报错,不需要可注释掉
#access_log /var/www/mysite/logs/access.log;
#error_log /var/www/mysite/logs/access.log;
#默认请求,nginx反向代理(动态页面转发至gunicorn)
location / {
#将访客IP加入headers中,否则获取到的将是127.0.0.1
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
#如果请求的文件不存在,则将路由转发到gunicorn的8000端口
if (!-f $request_filename) {
proxy_pass http://127.0.0.1:8000;
break;
}
}
#静态文件请求转发给目录
location ^~ /static/ {
root /var/www/mysite/app;
}
}
上面的内容中proxy_pass http://127.0.0.1:8000; 是表示动态页面转发到本机8000端口,这个端口就是gunicorn开放的服务。
这样静态页面nginx就直接返回给访客,动态页面则转发给gunicorn处理。
这里插一句:由于使用nginx反向代理到gunicorn,那么在flask中获取IP就需要
//X-Forward-For参数为nginx反向代理转发到gunicorn时设置的参数
ip = request.headers.get('X-Forward-For') or request.remote_addr
启用站点配置文件
cd /etc/nginx/sites-enabled
#添加引用链接
ln -s /etc/nginx/sites-available/mysite ./mysite
#查看引用是否成功
ls -l
检测配置文件是否有错误
sudo nginx -t
重启nginx
service nginx restart
开启防火墙端口
如果系统中没有安装ufw,则可以跳过,没有安装的话表现为命令不识别。
安装了ufw的话,如果相关端口没有开放,配置好nginx后会出现自己可以访问(wget网址试试),外网却无法访问
#查看开放的端口
ufw status
#添加80端口
ufw allow 80
安装Gunicorn
进入配置好的virtualenvs虚拟目录,激活网站虚拟环境
cd /var/virtualenvs
source mysite_venv/bin/activate
安装Gunicorn
pip install gunicorn
#进入网站根目录
cd /var/www/mysite
#创建配置文件
vi gunicorn.conf
输入配置文本并保存:
# 进程为5
workers = 5
# 监听本地8000端口,之后这个端口来的就是看这个网站的。
bind = '127.0.0.1:8000'
#如果要搭配gevent使用,请加上取消注释
#worker_class="gevent" #sync, gevent,meinheld
注意:如果需要使用gevent模式,请先pip install gevent,然后在gunicorn.conf配置文件中加上worker_class="gevent",其他都和往常一样。
gunicorn启动测试
cd /var/www/mysite
gunicorn -c gunicorn.conf myapp:app
启动后提示:
到这里gunicorn已经安装并配置好了,如果要正常用gunicorn启动网站项目,需要项目中有对应的启动文件,现在可以先跳过这一步,直接跳到安装Supervisor。
当我们安装并配置好 gunicorn 之后,需要用 gunicorn 启动 flask,注意网站项目中 manage.py里面的 app.run(),这句代码是作为 flask 自带的server服务的启动 入口,由于flask自带的server很性能很差,这里我们服务器上使用 gunicorn,manage.py和myapp.py一样,都是作为启动入口文件,供server调用运行。在项目的manage.py文件中,gunicom不会执行代码中的.run(),是需要加上一段代码对接gunicom。
在网站项目中需要一个gunicorn的启动入口的文件,如果没有就自己新建一个文件,名字无所谓,我取的是myapp.py,
内容为
import os
from app import create_app,db
app = create_app(os.getenv('mysite_CONFIG') or 'default')
#使用Gunicorn需要这两行代码对接
from werkzeug.contrib.fixers import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app)
这个文件和manage.py一样,也是一个启动文件,不同的是,myapp.py专门作为gunicorn启动使用,manage.py是用作flask自带的web-server启动,同时manage.py里面还有一些管理代码,一样可以使用python manage.py shell或python manage.py db init等命令来管理数据库。
运行Gunicorn,
--config gunicorn.conf是根据配置文件来运行
manage为自己的run文件
gunicorn -c gunicorn.conf myapp:app
安装Supervisor
我们的网站现在虽然能访问了,但是假如你重启服务器,网站的动态文件就会打不开,因为gunicorn不会开机自己启动,需要一个小保姆开机后自动给他启动,这里我们就使用supervisor。
Supervisor是一款服务器管理工具,用于监控和守护进程。阿里云会偶尔宕机,宕机后会切换物理服务,造成服务器重启。故而官网也强调过,程序最好有自动重启、重连机制。所以我们需要Supervisor当保姆,照顾我们的后台进程。
apt-get install supervisor
注意:supervisor需要系统默认是python2.7才能兼容支持,否则会安装失败,使用python -V查看系统默认py版本
向supervisor添加gunicorn的启动项
cd /etc/supervisor/conf.d
vi mysite.conf
粘贴一下文本并保存
# 进程的名字,取一个以后自己一眼知道是什么的名字。(这行字不能删,第一行需要一行注释,删了就有问题)
[program:mysite]
# 定义Gunicorn启动命令,我们手动在ssh启动Gunicorn需要cd到网站目录然后输入 gunicorn -c gunicorn.conf myapp:app,所以这里所有路径都要写成绝对路径,这样系统才能找到这些路径
command=/var/virtualenvs/mysite_venv/bin/gunicorn myapp:app -c /var/www/mysite/gunicorn.conf
# 网站目录
directory=/var/www/mysite
# 进程所属用户
user=root
# 自动重启设置。
autostart=true
autorestart=true
# 日志存放位置(可能造成print中文UnicodeEncodeError)
#stdout_logfile=/var/www/mysite/logs/gunicorn_supervisor.log
# 设置环境变量。这里这行的意思是:设置环境变量MODE的值为UAT。请根据自己的需要配置,如没有需要这行可以删除。
#environment = MODE="UAT"
[supervisord]
保存后就进入supervisorctl控制台
supervisorctl
进入控制台
reread
update
start mysite
启动完成后,以后每次开机supervisor都会帮我们自动按照配置文件启动gunicorn服务。
如果发生错误请退出控制台,尝试重启服务
service supervisor restart
现在重启服务器后,如果网站能正常访问了,说明gunicorn自动启动了,这也表示我们的supervisor配置成功了。
以后如果更新了网站项目文件,让gunicorn重新加载新的项目文件也只需要使用supervisor管理gunicorn进程就好了。
重新载入配置文件并停止所有进程并按新的配置启动:supervisorctl reload
以下是所有supervisorctl 的命令
supervisorctl status: 查看当前运行的进程列表
supervisorctl stop xxx: 停止某一个进程(xxx),xxx为[program:theprogramname]里配置的值。
supervisorctl start xxx: 启动某个进程
supervisorctl restart xxx: 重启某个进程
supervisorctl stop groupworker: 重启所有属于名为groupworker这个分组的进程(start,restart同理)
supervisorctl stop all,停止全部进程,注:start、restart、stop都不会载入最新的配置文件。
supervisorctl reload,载入最新的配置文件,停止原有进程并按新的配置启动、管理所有进程。
supervisorctl update,根据最新的配置文件,启动新配置或有改动的进程,配置没有改动的进程不会受影响而重启。
注意:显示用stop停止掉的进程,用reload或者update都不会自动重启。
supervisor使用中遇到的一些错误
============错误A
参考https://www.v2ex.com/t/210122
如果提示unix:///var/run/supervisor.sock no such file
error: <class 'socket.error'>, [Errno 2] No such file or directory: file: /usr/lib/python2.7/socket.py line: 224
这表明supervisord服务端没有成功启动,多半是/etc/supervisor/conf.d下面自己的配置文件出问题
cd /etc/supervisor/conf.d
supervisord -c mysite.conf
这里就告诉我配置文件17行出了问题
修改好配置文件后,
#重新生成supervisor.sock文件,启动监听服务
supervisord -c supervisord.conf
#重新加载自定义配置文件
supervisorctl reload
============错误B
如果配置文件有错误,会提示你提示
如果有错误则exit退出控制台,vi mysite.conf修改错误后再继续进入控制台,并reread重新读取配置文件。
如果都正确了,则在supervisorctl的控制台中输入命令,启动supervisor任务。
(注意:如果要supervisor启动任务,则会启动gunicorn,自己先使用gunicorn命令试试能否正常启动网站项目)。
#进入网站目录
cd /var/www/mysite
#测试能否正常启动网站项目
gunicorn -c gunicorn.conf myapp:app
如果能正常启动就ctrl+c结束,然后继续进入supervisorctl启动任务。
supervisorctl
==============错误C
这样就错误:
[program:taokeapi]
# 定义Gunicorn启动命令,我们手动在ssh启动Gunicorn需要cd到网站目录然后输入 gunicorn -c gunicorn.conf myapp:app,所以>这里所有路径都要写成绝对路径,这样系统才能找到这些路径
command=/var/virtualenvs/taokeapi_venv/bin/gunicorn myapp:app -c /var/www/taokeapi/gunicorn.conf
# 网站目录
directory=/var/www/taokeapi
# 进程所属用户
user=root
# 自动重启设置。
autostart=true
autorestart=true
[supervisord]
这样就正确:
# 进程的名字,取一个以后自己一眼知道是什么的名字。
[program:taokeapi]
# 定义Gunicorn启动命令,我们手动在ssh启动Gunicorn需要cd到网站目录然后输入 gunicorn -c gunicorn.conf myapp:app,所以>这里所有路径都要写成绝对路径,这样系统才能找到这些路径
command=/var/virtualenvs/taokeapi_venv/bin/gunicorn myapp:app -c /var/www/taokeapi/gunicorn.conf
# 网站目录
directory=/var/www/taokeapi
# 进程所属用户
user=root
# 自动重启设置。
autostart=true
autorestart=true
[supervisord]
差别仅仅是第一行多了一行注释。。。
不知道是BUG还是什么,总之第一行需要注释,去掉就会出问题。。。
======错误D
使用supervisor启动gunicorn,执行print就出错。
而直接启动gunicorn则没问题。
可见错误在supervisor上面。。
经过多次排查,发现,
vi /etc/supervisor/conf.d/taokeapi.conf配置文件中多了一行,
stdout_logfile=/var/www/mysite/logs/gunicorn_supervisor.log
由于supervisor是基于python2,当运行python3的项目时,print就会被写入这个日志文件,python2在有些系统中输出中文就会出现UnicodeEncodeError错误。
解决办法:
配置文件中去掉这行输出日志目录,完整配置如下:
# 进程的名字,取一个以后自己一眼知道是什么的名字。
[program:taokeapi]
# 定义Gunicorn启动命令,我们手动在ssh启动Gunicorn需要cd到网站目录然后输入 gunicorn -c gunicorn.conf myapp:app,所以>这里所有路径都要写成绝对路径,这样系统才能找到这些路径
command=/var/virtualenvs/taokeapi_venv/bin/gunicorn myapp:app -c /var/www/taokeapi/gunicorn.conf
# 网站目录
directory=/var/www/taokeapi
# 进程所属用户
user=root
# 自动重启设置。
autostart=true
autorestart=true
[supervisord]
然后重新加载配置文件
supervisord -c taokeapi.conf
supervisorctl
>reread
>update
>reload
这样就发现没问题了