WSGI協議
Web框架致力於如何生成HTML代碼,而Web服務器用於處理和響應HTTP請求。Web框架和Web服務器之間的通信,需要一套雙方都遵守的接口協議。WSGI協議就是用來統一這兩者的接口的。
WSGI容器——Gunicorn
常用的WSGI容器有Gunicorn和uWSGI,但Gunicorn直接用命令啟動,不需要編寫配置文件,相對uWSGI要容易很多,所以這里我也選擇用Gunicorn作為容器。
安裝
1
|
pip install gunicorn
|
啟動
1
|
$ gunicorn [options] module_name:variable_name
|
module_name
對應python文件,variable_name
對應web應用實例。
以最簡單的flask應用為例:
1
2
3
4
5
6
7
8
9
10
|
#main.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'hello world'
if __name__ == '__main__':
app.run()
|
啟動代碼:
1
|
gunicorn --worker=3 main:app -b 0.0.0.0:8080
|
tips
開發flask應用時,常用flask-script添加一些命令擴展。而部署應用時,就不需要再從flask-script的Manager實例中啟動應用了。
在項目中添加wsgi.py文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# -*- coding: utf-8 -*-
import os
from . import create_app
import datetime
# Create an application instance that web servers can use. We store it as
# "application" (the wsgi default) and also the much shorter and convenient
# "app".
application = app = create_app('default')
@app.context_processor
def template_extras():
"""
上下文處理裝飾器,返回的字典的鍵可以在上下文中使用
:return:
"""
return {'enumerate': enumerate, 'len': len, 'datetime': datetime}
|
- 在wsgi文件中創建flask實例給gunicorn使用。
- 創建實例后,注冊上下文裝飾器。
再通過gunicorn啟動flask應用:
1
|
gunicorn -b 127.0.0.1:8000 -k gevent -w 1 app.wsgi
|
Nginx
Gunicorn對靜態文件的支持不太好,所以生產環境下常用Nginx作為反向代理服務器。
安裝
1
|
sudo apt-get install nginx
|
啟動
1
|
sudo /etc/init.d/nginx start
|
修改配置文件
先將配置文件備份:
1
|
cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak
|
然后修改配置文件:
1
2
3
4
5
6
7
8
9
10
11
12
|
server {
listen 80;
server_name _; # 外部地址
location / {
proxy_pass http://127.0.0.1:8000;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
|
這里將Nginx設置為代理模式,代理到本地的8000端口,之后就可以通過公網訪問flask應用了。
總結
最后,總結下這幾個部分的關系:
(nginx收到客戶端發來的請求,根據nginx中配置的路由,將其轉發給WSGI)
nginx:”WSGI,找你的來了!”廈門叉車租賃
(WSGI服務器根據WSGI協議解析請求,配置好環境變量,調用start_response方法呼叫flask框架)
WSGI服務器:”flask,快來接客,客戶資料我都給你准備好了!”
(flask根據env環境變量,請求參數和路徑找到對應處理函數,生成html)
flask:”!@#$%^……WSGI,html文檔弄好了,拿去吧。”
(WSGI拿到html,再組裝根據env變量組裝成一個http響應,發送給nginx)
WSGI服務器:”nginx,剛才誰找我來着?回他個話,!@#$%^…..”
(nginx再將響應發送給客戶端)