Docker+Gunicorn+Flask部署項目(轉載)
(一) Flask 應用
1. 創建一個目錄并切換進去
$ mkdir gunicorn_demo
$ cd gunicorn_demo
2. 創建一個 Flask 應用
構建一個最基本的 Flask 項目
app.py 文件
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return 'Hello World'
(二) Gunicorn 相關
1. 后端工作的簡單示意圖

2. Gunicorn 概述
Gunicorn 是目前使用最廣泛的高性能的 Python WSGI(WEB Server Gateway interface)服務器,移植自 Ruby 的 Unicorn 項目,使用 pre-fork worker 模式,具有簡單、易用、輕量級、低資源消耗和高性能等特點。
什么是 pre-fork worker 模型?
worker模型意味著:這個模型有一個中心主控 master進程,由它來管理一組 worker 進程;這個主控進程并不知曉任何客戶端,所有的請求和響應都完全是由多個 worker 進程來處理的。fork意味著:worker 進程是由 master 進程 fork (復刻)出來的;pre-意味著:在任何客戶端請求到來之前(程序啟動的時候),就已從 master 進程 fork 出了多個 worker 進程,坐等請求到來。
3. Gunicorn 的工作方式
存放在 /gunicorn/workers/__init__.py 文件中
以下針對每一個 worker 進程中的工作模式
sync:單進程單線程的工作模式,而且還是同步的,也就是說當前請求未處理結束,其他請求只能排隊等待eventlet:單進程單線程多協程的工作模式(異步)gevent:單進程單線程多協程的工作模式(異步)gthread:單進程多線程的工作模式...還有一些其他工作模式,具體請看官方文檔![image]()
注意事項:
- Gunicorn 建議設置的 workers 的數量為
(2 * CPU) + 1 - Gunicorn 默認啟動的工作方式為
sync模式 - Gunicorn 中的多線程和多協程的工作方式是互斥的,也就是說在一個 worker 進程中,
單進程多線程和單進程單線程多協程這兩種工作方式是可以的,但是單進程多線程多協程目前是不可以的
4. Gunicorn 的參數配置
| 參數名 | 描述 | 默認值 |
|---|---|---|
| bind、 -b、 --bind | 服務監聽地址和端口 | 127.0.0.1:8000 |
| backlog、--backlog | 等待連接的最大數 | 2048 |
| workers、 -w、 --workers | 用于處理工作進程的數量 | 1 |
| worker_class、 -k、 --worker-class | 工作模式 | sync |
| threads、 --threads | 一個worker中的工作線程數 | 1 |
| worker_connections、 --worker-connections | 同時連接的客戶端的最大數量,只影響 eventlet 和 gevent 類型 | 1000 |
| keepalive、 --keep-alive | 在 Keep-Alive 連接上等待請求的秒數。 | 2 |
| debug | debug 模式 | - |
| proc_name、 -n、 --name | 進程名 | None |
| loglevel、 --log-level | 日志級別 | - |
更具體的內容請查看文檔:Gunicorn Settings
5. 運行方式一(命令行 + 運行參數)
① 同步
$ gunicorn --workers=5 app:app
以上開啟了 5 個 worker 進程,默認是以 sync 的工作模式運行的,也就是 同步 的工作模式
第一個 app 指的是 app.py 文件名
第二個 app 指的是文件中的實例變量 app
② 多線程
$ gunicorn --workers=5 --threads=2 app:app
# 等同于
$ gunicorn --workers=5 --threads=2 --worker-class=gthread app:app
開啟了 5 個 workder 進程,每個進程中有兩個線程,這里最大的并發請求數就是 worker * 線程數 = 10
③ 協程
$ gunicorn --workers=5 --worker-connections=1000 --worker-class=gevent app:app
開啟了 5 個 workder 進程,每個進程中默認是一個線程,然后開啟的協程數為 1000,在這種情況下,能夠處理的最大并發請求數量為 worker * 協程數 = 5000
6. 運行方式二(將運行參數信息放到配置文件中)
在項目根目錄上創建 gunicorn_config.py 文件,內容如下:
"""gunicorn + gevent 的配置文件"""
# 多進程
import multiprocessing
# 綁定ip + 端口
bind = '0.0.0.0:5000'
# 進程數 = cup數量 * 2 + 1
workers = multiprocessing.cpu_count() * 2 + 1
# 等待隊列最大長度,超過這個長度的鏈接將被拒絕連接
backlog = 2048
# 工作模式--協程
worker_class = 'gevent'
# 最大客戶客戶端并發數量,對使用協程的 worker 的工作有影響
# 服務器配置設置的值 1000:中小型項目 上萬并發: 中大型
worker_connections = 1000
# 進程名稱
proc_name = 'gunicorn.pid'
# 進程 pid 記錄文件
pidfile = 'gunicorn.pid'
# 日志等級
loglevel = 'warning'
# 日志文件名
logfile = 'gunicorn_log.log'
# 設置訪問日志
accesslog = 'gunicorn_acess.log'
# 設置錯誤信息日志
errorlog = 'gunicorn_error.log'
# 代碼發生變化是否自動重啟
reload = True
命令行運行:
$ gunicorn -c gunicorn_config.py app:app
(三) Docker 部署 Flask
1. 編寫 Dockerfile 文件
app.py 和 Dockerfile 文件在同一個目錄下
Dockerfile 文件的內容
# 指定下載 python 版本,說明該鏡像以哪個鏡像為基礎
FROM python:3.8.5
# 構建者的基本信息
MAINTAINER whxcer
# 創建 app 文件夾
RUN mkdir -p /app
# 進入 app 目錄
RUN cd /app
# 或 WORKDIR /app
# 在容器內部執行的命令
# 注意:gunicorn 與 gevent 存在版本依賴關系,此外 gevent 依賴的 greenlet 也會有版本問題,盡量使用最新版本即可
# RUN pip install -r requirements.txt -i https://pypi.douban.com/simple/
RUN pip install -i https://pypi.douban.com/simple/ flask
RUN pip install -i https://pypi.douban.com/simple/ gunicorn
RUN pip install -i https://pypi.douban.com/simple/ gevent
RUN pip install -i https://pypi.douban.com/simple/ greenlet
# 將 linux 系統當前目錄下的內容拷貝到容器的 /app 目錄下
ADD . /app
# 暴露 5000 端口
EXPOSE 5000
# 將 app 文件夾為工作目錄
WORKDIR /app
# 容器啟動的時候執行的命令 flask run(使用內置的開發服務器啟動)
# CMD ["flask", "run", "--host", "0.0.0.0"]
# 使用 Gunicorn 服務器啟動 Flask 應用
CMD ["gunicorn", "-c", "gunicorn_config.py", "app:app"]
此時的文件結構為:
├── gunicorn_demo
│ ├── app.py
│ ├── Dockerfile
│ ├── gunicorn_config.py
2. 構建鏡像
# 構建鏡像
docker build -t="gunicorn_demo" .
或
docker build -t gunicorn_demo .
# 查看構建之后的鏡像
docker images
3. 使用鏡像,啟動容器
# 使用鏡像,啟動容器
docker run -d -p 5000:5000 gunicorn_demo
# 查看啟動后的容器
docker ps
# 將處于運行狀態的容器暫停
docker stop container_id
4. 運行效果圖
- 使用 Flask 內置的開發服務器啟動的效果圖
![image]()
- 使用 Gunicorn 服務器啟動的效果圖
![image]()
分類: Docker




浙公網安備 33010602011771號