作者:Chancel, 更新:2019 Sep 06, 字数:6727, 已阅:798
后端程序是用Flask写的,之前是采用Gunicorn+Nginx进行部署的,最近打算换成uwsgi的方式
超文本传输协议(英语:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信的基础。
http协议是基本的协议之一,底层使用TCP协议,通过浏览器等工具,发起一个HTTP请求到指定服务器的指定端口,一旦收到请求,服务器会立刻返回一个状态,这就是HTTP协议
关于HTTP协议可以直接参考超文本传输协议 - 维基百科
Web服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI)是为Python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。自从WSGI被开发出来以后,许多其它语言中也出现了类似接口。
WSGI是基于现存的CGI标准而设计的,WSGI其实是一种中间件,实现了API交互双方所需要的数据规范,因此可以在WSGI服务器与WSGI应用起调节作用
用Python语言写一个符合WSGI规范的Hello world程序如下所示
def app(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/plain')])
yield "Hello world!\n"
更详细的数据依旧可以参考Web服务器网关接口 - 维基百科
无论是Django还是Flask都是自带了一个实现了WSGI协议的Server以及Application来方便你专心写Web服务,但这个Server不保障其性能,故可用于本地调试但不可用于生产环境下
而无论是gunicorn还是uWSGI的本质都是实现了WSGI协议的Web服务器
这里创建一个最小的Application,并假设这个就是你的Flask应用
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "<h1 style='color:blue'>Hello There!</h1>"
if __name__ == "__main__":
app.run(host='0.0.0.0',port=8889)
尝试启动下你的应用
python hello.py
# 输出
# chancel @ chancel-cp in /tmp/flask [17:20:11]
$ python hello.py
* Serving Flask app "hello" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:8889/ (Press CTRL+C to quit)
访问下 http://127.0.0.1:8889,可以得到蓝色的Hello world标题
关闭上面的运行,进入安装gunicorn/uwsgi的环节,如无特别说明,以下操作均在/tmp/flask目录中完成(即你的项目文件)
首先是安装gunicorn
pip install gunicorn
启动gunicorn
# hello是你的程序入口文件名(app.py/__init__.py等,不需要带后缀),app是你的flask实例变量名
gunicorn --bind 0.0.0.0:5000 hello:app
# 输出
# chancel @ chancel-cp in /tmp/flask [17:24:54] C:130
$ gunicorn --bind 0.0.0.0:8889 hello:app
[2019-09-06 17:25:02 +0800] [16092] [INFO] Starting gunicorn 19.9.0
[2019-09-06 17:25:02 +0800] [16092] [INFO] Listening at: http://0.0.0.0:8889 (16092)
[2019-09-06 17:25:02 +0800] [16092] [INFO] Using worker: sync
[2019-09-06 17:25:02 +0800] [16095] [INFO] Booting worker with pid: 16095
这个时候gunicorn已经运行起来了,接下来我们要考虑怎么后台运行这个程序了,这里考虑两种方式
以前的文章写了不少关于如何设置supervisor的方式,这里介绍一下如何设置程序为systemd吧
systemd是什么?
systemd是Linux计算机操作系统之下的一套中央化系统及设置管理程序(init),包括有守护进程、程序库以及应用软件,由Lennart Poettering带头开发。
无论是sshd服务还是firewalld服务,只要是使用systemctl start <service_name>格式的均是属于systemd管理程序,其配置文件均存放于 /etc/systemd/system/ 目录下
首先我们编辑创建gunicorn的systemd配置文件
# 文件名既是服务名,根据需要自行定制
vim /etc/systemd/system/gunicorn.service
[Unit] # Unit 多存放描述信息以及启动条件
Description=Gunicorn instance to serve flask
After=network.target # 如果开机启动的话,在网络初始化完毕之后启动
[Service]
User=chancel # 程序运行的用户
Group=chancel # 程序运行的组
WorkingDirectory=/tmp/flask/ # 程序目录
Environment="PATH=/tmp/flask/flaskenv/bin" # 程序环境变量,如设置了venv则需要填写此项
ExecStart=/tmp/flask/flaskenv/bin/gunicorn --workers 3 --bind unix:flask.sock -m 007 hello:app # 启动命令
[Install]
WantedBy=multi-user.target
最后我们使用systemctl来启动程序以及设计开机自启
sudo systemctl start gunicorn
sudo systemctl enable gunicorn
首先安装uwsgi
pip install uwsgi
创建uwsgi配置文件
vim /tmp/flask/uwsgi.ini
[uwsgi]
module = hello:app
master = true
processes = 5 # 进程数量
chdir = /tmp/flask
socket = /tmp/flask/uwsgi.sock # 设置为socks协议,不走http协议(据说效率更高,没有考证)
chmod-socket = 660 # socket权限
vacuum = true
die-on-term = true
# 日志记录交由supervisor管理
logto = /tmp/flask/flasg.log # 日志输出
启动uwsgi
uwsgi /tmp/flask/uwsgi.ini
上面已经介绍过Systemd了,这里直接编辑创建uwsgi的systemd配置文件,大体配置是相似的
# 文件名既是服务名,根据需要自行定制
vim /etc/systemd/system/uwsgi.service
[Unit] # Unit 多存放描述信息以及启动条件
Description=Uwsgi instance to serve flask
After=network.target # 如果开机启动的话,在网络初始化完毕之后启动
[Service]
User=chancel # 程序运行的用户
Group=chancel # 程序运行的组
WorkingDirectory=/tmp/flask/ # 程序目录
Environment="PATH=/tmp/flask/flaskenv/bin" # 程序环境变量,如设置了venv则需要填写此项
ExecStart=/tmp/flask/flaskenv/bin/Uwsgi /tmp/flask/uwsgi.ini
[Install]
WantedBy=multi-user.target
最后我们使用systemctl来启动程序以及设计开机自启
sudo systemctl start uwsgi
sudo systemctl enable uwsgi
首先安装Nginx
rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
yum install nginx -y
设置开机启动
systemctl start nginx
systemctl enable nginx
Nginx的默认配置文件位于 /etc/nginx/nginx.conf,建议采用导入配置文件的方式,参考下面的配置文件,重点在于 *include /etc/nginx/conf.d/.conf;**
user chancel;
worker_processes 1;
error_log /var/log/nginx/error.log;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# gzip设置
gzip on;
gzip_comp_level 9;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png application/vnd.ms-fontobject font/ttf font/opentype font/x-woff image/svg+xml;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";
gzip_buffers 32 4k;
...
include /etc/nginx/conf.d/*.conf; # 导入/etc/nginx/conf.d/目录下所有.conf配置文件
}
配置Nginx.conf之后,如果是采用gunicorn的部署方式,在 /etc/nginx/conf.d/目录下新增一个flask.conf的配置,并参考下面的配置
server {
listen 80;
access_log /var/log/nginx/flask_access.log;
error_log /var/log/nginx/flask_error.log;
location / {
# 这里将部分头信息转发到Flask应用
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header HTTP_X_FORWARDED_FOR $remote_addr;
proxy_pass http://127.0.0.1:5000;
}
}
如果是uwsgi配置,由于是采用socks通信的,配置与gunicorn差异主要表现在代理地址与重写转发头处
server {
listen 80;
access_log /var/log/nginx/flask_access.log;
error_log /var/log/nginx/flask_error.log;
location / {
include uwsgi_params;
uwsgi_param Host $host;
uwsgi_param X-Real-IP $remote_addr;
uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
uwsgi_param HTTP_X_FORWARDED_FOR $remote_addr;
uwsgi_pass_request_headers on;
uwsgi_pass unix:/opt/api/uwsgi.sock;
}
}
到这里本篇就结束了,感谢阅读