nginx + gunicorn + flask + supervisor的搭建
为什么要加nginx。
Nginx能更好地直接处理静态资源(通过一些http request header),而把动态资源转发给后端服务器
Nginx也可以缓存一些动态内容
Nginx可以进行多台机器的负载均衡
Nginx可以更方便的实施一些安全策略。gunicorn 直接暴露还是蛮危险的,nginx挡一层,过滤掉一些恶意IP,同样的gunicorn处理起来就比较麻烦了。
nginx常见的两种代理方式:
正向代理:{ 客户端 ---》 代理服务器 } ---》 服务器
反向代理:客户端 ---》 { 代理服务器 ---》 服务器 }
{} 表示局域网
gunicorn:
flask自带的app.run()服务,稳定性等各方面都不足,只适用于测试环境,线上环境还是要有专门的服务器,gunicorn和uWsgi就是常用的两个解决方案。
supervisor:
Linux的后台进程运行有好几种方法,例如nohup,screen等,但是,如果是一个服务程序,要可靠地在后台运行,我们就需要把它做成daemon,最好还能监控进程状态,在意外结束时能自动重启。
supervisor就是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时能自动重启。
网络架构:
环境:
Ubuntu 15.10
1. 安装pip和virtualenv
rot@rot-virtual-machine:~$ sudo apt-get install python-pip python-vitualenv
2. 创建独立环境。
# home目录下的操作就不用sudo了 rot@rot-virtual-machine:~$ cd ~ #必须到用户目录,否则在以后的安装gunicorn会由于权限问题失败 rot@rot-virtual-machine:~$ sudo mkdir -p pythonapp/dffyb rot@rot-virtual-machine:~$ cd pythonapp/dffyb rot@rot-virtual-machine:~/pythonapp/dffyb$ vitualenv venv rot@rot-virtual-machine:~/pythonapp/dffyb$ source venv/bin/activate # 使用虚拟环境,看下一步linux提示符的变化,开头多了一个(venv) (venv)rot@rot-virtual-machine:~/pythonapp/dffyb$ pip install flask (venv)rot@rot-virtual-machine:~/pythonapp/dffyb$ pip install gunicorn #安装成功后,进入venv/bin/目录,会有一个gunicorn文件,否则安装失败。 (venv)rot@rot-virtual-machine:~/pythonapp/dffyb$ deactivate #退出venv环境 rot@rot-virtual-machine:~/pythonapp/dffyb$ vim runserver.py #创建一个flask引入文件 #!/usr/bin/python from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return "hello world" if __name__ == '__main__': app.run(debug = True)
3. 配置gunicorn。
rot@rot-virtual-machine:~/pythonapp/dffyb/venv$ vim gunicorn.conf workers = 3 # 服务器内核数 bind = '127.0.0.1:8000' # gunicorn开启的服务地址和端口,默认8000
4. 配置supervisor。
rot@rot-virtual-machine:~$ sudo apt-get install supervisor rot@rot-virtual-machine:~$ whereis supervisor supervisor: /etc/supervisor rot@rot-virtual-machine:~$ cd /etc/supervisor rot@rot-virtual-machine:~/etc/supervisor$ cd conf.d rot@rot-virtual-machine:~/etc/supervisor/conf.d$ sudo vim dffyb.conf [program:dffyb] #进程唯一名称,操作进程时候用 command=/home/rot/pythonapp/dffyb/venv/bin/gunicorn runserver:app -c /home/rot/pythonapp/dffyb/venv/gunicorn.conf # 创建进程的命令 directory=/home/rot/pythonapp/dffyb # 创建进程时的所在目录 user=www #所属用户 autostart=true #自动开启 autorestart=true #自动重启 stdout_logfile=/var/log/supervisor/gunicorn_supervisor.log stderr_logfile=/var/log/supervisor/gunicorn_supervisor.err rot@rot-virtual-machine:~$ sudo supervisorctl reread # 重新读取配置文件 rot@rot-virtual-machine:~$ sudo supervisorctl update # 更新配置文件 rot@rot-virtual-machine:~$ sudo supervisorctl start dffyb # 启动 gunicorn rot@rot-virtual-machine:~$ sudo supervisorctl stop dffyb # 停止 gunicorn rot@rot-virtual-machine:~$ sudo supervisorctl status # 查看状态 rot@rot-virtual-machine:~$ curl # 如果返回hello world,说明服务成功开启
command=/home/rot/pythonapp/dffyb/venv/bin/gunicorn runserver:app -c /home/rot/pythonapp/dffyb/venv/gunicorn.conf # 解释
/home/rot/pythonapp/dffyb/venv/bin/gunicorn # gunicorn 安装路径
runserver:app # 跑的文件名,runserver.py , app runserver.py 中创建的app变量名,其实runserver.py中的app.run()可以不要,在这里会自动执行。
5. nginx配置。
rot@rot-virtual-machine:~$ sudo apt-get install nginx rot@rot-virtual-machine:~$ sudo cp /etc/nginx/sites-available/default dffyb.conf rot@rot-virtual-machine:~$ sudo vim /etc/nginx/sites-available/dffyb.conf server { listen 80; server_name dffyb.com; root /home/rot/pythonapp/dffyb; access_log /home/rot/logs/access.log; error_log /home/rot/logs/error.log; location / { proxy_set_header X-Forward-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; if (!-f $request_filename) { proxy_pass http://127.0.0.1:8000; break; } } } rot@rot-virtual-machine:~$ sudo nginx -t # 测试一下配置文件 rot@rot-virtual-machine:~$ sudo service nginx start rot@rot-virtual-machine:~$ sudo nginx -s reload # 平滑重启 rot@rot-virtual-machine:~$ curl # hello world 就成功了、