为什么80%的码农都做不了架构师?>>>
nginx + gunicorn + flask + supervisor的搭建
为什么要加nginx。
Nginx能更好地直接处理静态资源(通过一些http request header),而把动态资源转发给后端服务器
Nginx也可以缓存一些动态内容
Nginx可以进行多台机器的负载均衡
Nginx可以更方便的实施一些安全策略。gunicorn 直接暴露还是蛮危险的,nginx挡一层,过滤掉一些恶意IP,同样的gunicorn处理起来就比较麻烦了。
nginx常见的两种代理方式:
正向代理:{ 客户端 ---》 代理服务器 } ---》 服务器
反向代理:客户端 ---》 { 代理服务器 ---》 服务器 }
{} 表示局域网
gunicorn:
flask自带的app.run()服务,稳定性等各方面都不足,只适用于测试环境,线上环境还是要有专门的服务器,gunicorn和uWsgi就是常用的两个解决方案。
guincorn是支持wsgi协议的http server,gevent只是它支持的模式之一 ,是为了解决django、flask这些web框架自带wsgi server性能低下的问题。
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()可以不要,在这里会自动执行。
centos下
[root@www web] vim /etc/supervisord.conf
#添加
[program:ny108]
command=/data/www/p_ny108com/venv/bin/gunicorn runserver:app -c /data/www/p_ny108com/venv/gunicorn.conf
directory=/data/www/p_ny108com
user=www
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/gunicorn_supervisor.log
stderr_logfile=/var/log/supervisor/gunicorn_supervisor.err
[root@www web] supervisord -c /etc/supervisord.conf
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 就成功了、