Flask 生產環境部署(Falsk + uWSGI + nginx)

今天学了微积分發表於2024-04-14

前言

最近自己做了個 Falsk 小專案,在部署上伺服器的時候,發現雖然不乏相關教程,但大多都是將自己專案程式碼複製出來,不講核心邏輯,不太簡潔,於是將自己部署的經驗寫成內容分享出來。

uWSGI 簡介

uWSGI: 一種實現了多種協議(包括 uwsgi、http)並能提供伺服器搭建功能的 Python 包

Difference between WSGI , uWSGI and UWSGI

在 Flask 和 nginx 之間使用 uWSGI 的必要性:nginx 並不能直接與 Python 中的 WSGI 通訊。WSGI 是 Python 中網路服務的標準。What is the point of uWSGI?

uWSGI 安裝

pip 安裝,如果失敗則用 conda 安裝。Error installing uwsgi in virtualenv

Flask 注意

既然看到這篇內容 Flask 程式編寫肯定已經不是問題了,不過多介紹。Flask 官網中 Quickstart 的程式碼為

# app.py
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
    return "<p>Hello, World!</p>"

透過 flask --app hello run 啟動。

要提的是程式碼中如果有 app.run(),要將其放在 if __name__ == "__main__": 中,即:

# app.py
if __name__ == "__main__":
    app.run()

快速上手 uWSGI

檔案目錄下執行:uwsgi --http 0.0.0.0:5001 -w app:app。第一個 app 是 Flask 程式碼檔名,第一個 app 是程式碼中 Flask 物件變數名,即賦值為 Flask(__name__) 的變數名。

開啟瀏覽器訪問對應埠測試

部署

部署上伺服器需要新增名為 uwsgi.ini 的 uwsgi 配置檔案,放在專案根目錄下。

基本配置:

; uwsgi.ini
[uwsgi]
module = app:app
; http 和 socket 二選一
; socket 用的是 uwsgi 協議通訊
; http = 127.0.0.1:3031
socket = 127.0.0.1:3031
daemonize = ./uwsgi/uwsgi.log ; 後臺執行
pidfile = ./uwsgi/uwsgi.pid   ; 儲存 pid 方便後臺執行時的程式管理

並在根目錄下建立 uwsgi 資料夾,就能執行最基礎的伺服器了。

  • 啟動:uwsgi --ini uwsgi.ini
  • 關閉:uwsgi --stop ./uwsgi/uwsgi.pid
  • 配置檔案更改後:uwsgi --reload ./uwsgi/uwsgi.pid

配置檔案中的變數名就是命令列中引數名的全稱。

還建議配置:

master = 1
processes = 4
; 上面兩個引數配置併發,根據伺服器效能配置
enable-threads = 1  ; 開啟多執行緒
stats = 0.0.0.0:9191  ; 開啟監控埠,以 json 格式返回當下 uwsgi 執行狀態
stats-http = 1        ; 開啟 http 訪問監控埠

奇怪的是在本地測試時可以在瀏覽器直接訪問 9191 埠,而在服務員上部署成功後卻無法訪問,但是有返回的內容,可以用 curl 獲取內容。

除此之外,要監控 uwsgi 的執行狀態,還可以透過 pip 安裝 uwsgitop,而後在 shell 中輸入 uwsgitop 就能檢視監控,就像 linux 中的 top 一樣。

nginx 配置

nginx 基礎不多介紹,直入正題配合使用 uwsgi 時該如何配置。

location 中照如下設定:

# 如果是用 socket:
location / {
    include uwsgi_params;
    uwsgi_pass 127.0.0.1:3031;    # 埠號和前述配置檔案一樣
}
# 如果是用 http:
location / {
    proxy_pass http://127.0.0.1:3031;  # 埠號和前述配置檔案一樣
}

現在可以透過瀏覽器訪問了。

20240416補充

原來無法訪問是埠的問題,uwsgi 的監控埠配置為 9191 後,nginx 做反向代理時不能同時使用 9191 埠,換個埠即可。

相關文章