python的web應(yīng)用部署方式本人在項(xiàng)目中使用過的:
- flask + gunicorn + supervisor + nginx
- docker
實(shí)現(xiàn)一個(gè)flask應(yīng)用
# app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'hello world'
使用flask自帶的wsgi(適合測試使用)啟動(dòng)
flask run
使用gunicorn啟動(dòng)
# gunicorn.conf.py
import multiprocessing
workers = multiprocessing.cpu_count() * 2 + 1 # --workers=5
workers_class = "gevent" # --workers-class=gevent
bind = "0.0.0.0:7070" # --bind=:7070
reload = True # --reload=True 代碼改動(dòng)后自動(dòng)重啟
accesslog = "/home/ubuntu/flaskapp/logs/gunicorn_access.log"
errorlog = "/home/ubuntu/flaskapp/logs/gunicorn_error.log"
可以使用gunicorn命令啟動(dòng)運(yùn)行
gunicorn app:app -c gunicorn.conf.py
supervisor管理應(yīng)用進(jìn)程
[program:gunicorn]
command=/path/to/gunicorn main:application -c /path/to/gunicorn.conf.py
directory=/path/to/project
user=nobody
autostart=true
autorestart=true
redirect_stderr=true
# 特別注意需在字符中有%號(hào)需要通過%號(hào)轉(zhuǎn)義%%
environment=SQLALCHEMY_DATABASE_URI = "mysql+pymysql://*%%*:**@**/test?charset=utf8",REDIS_URL="redis://**/11"
stdout_logfile=/home/ubuntu/flaskapp/logs/supervisor_out.log
stderr_logfile=/home/ubuntu/flaskapp/logs/supervisor_err.log
通過supervisorctl管理進(jìn)程
sudo supervisorctl reload
使用nginx做服務(wù)器
upstream host_name.com {
ip_hash; // *2*
server example1.com weight=4; // *4*, 默認(rèn)權(quán)重為1
server example2.com backup; //備機(jī),不能和ip_hash關(guān)鍵字一起使用
server example3.com max_fails=3 fail_timeout=30s; //指定最大的重試次數(shù),和重試時(shí)間間隔
}
#Nginx負(fù)載均衡有4種方案配置:
#1. 輪詢,配置文件中的順序,依次把客戶端的Web請(qǐng)求分發(fā)到不同的后端服務(wù)器上
#2. 最少連接, Web請(qǐng)求會(huì)被轉(zhuǎn)發(fā)到連接數(shù)最少的服務(wù)器上
#3. IP地址哈希,前述的兩種負(fù)載均衡方案中, 同一客戶端連續(xù)的Web請(qǐng)求可能會(huì)被分發(fā)到不同的后端服務(wù)器進(jìn)行處理, 因此如果涉及到會(huì)話Session, 那么會(huì)話會(huì)比較復(fù)雜. 常見的是基于數(shù)據(jù)庫的會(huì)話持久化. 要克服上面的難題, 可以使用基于IP地址哈希的負(fù)載均衡方案. 這樣的話, 同一客戶端連續(xù)的Web請(qǐng)求都會(huì)被分發(fā)到同一服務(wù)器進(jìn)行處理
#4. 基于權(quán)重, 請(qǐng)求更多地分發(fā)到高配置的后端服務(wù)器上, 把相對(duì)較少的請(qǐng)求分發(fā)到低配服務(wù)器
server {
listen 80;
server_name host_name.com;
location / {
proxy_pass http://host_name.com;
}
}
nginx可以作為反向代理和負(fù)載均衡的web服務(wù)器, gunicorn官網(wǎng)推薦使用nginx作為反向代理服務(wù)器
sudo service nginx start
docker容器部署
FROM python:3
WORKDIR $HOME/flaskapp
COPY . .
RUN pip install -r requirements.txt
CMD ["gunicorn", "app:app", "-c", "gunicorn.conf.py"]
docker可以將部署環(huán)境搭建在容器中, 使用起來相當(dāng)方便, 只需一個(gè)Dockefile文件, 再執(zhí)行docker build創(chuàng)建image, 然后運(yùn)行image
docker build -t 'flaskapp:v1' .
docker run 80:5000 flaskapp:v1