Try   HackMD

部署 Flask + Gunicorn + Nginx

如何使用Nginx, gunicorn與supervisor 進行搭配,來部署一個Flask App

分別先講一下這四個工具每個的工作:

  1. Flask: 後端程式,一個Python web framework
  2. Nginx: 反向代理
  3. Gunicorn: 幫助我們部署Flask App
  4. Supervisor: 監控與控制Gnuicron的程序(process)
  5. inotify-tools: 監控當後端的code改變時會自動的更新

先備知識

  • Program: 這座工廠要如何建造、規劃的藍圖
  • Process: 照著 Program 這張設計藍圖所完成的實體工廠
  • Thread: 工廠內的工人,確保工廠的每項功能,並且共享工廠內的每一項資源
  • Process 本身不是基本執行單位,而是 Thread (執行緒)的容器
  • 在多功作業系統(Multitasking Operating System)中,可以同時執行數個Process ,然而一個 CPU 一次只能執行一個 Process (因此才有現在的多核處理器)。
  • 一個 Process 至少包含一個 Thread
  • 一個 Process 可以同時擁有多個 Thread
  • 每個 thread共享 Process 的 code、data
  • 每個 thread 有自己的 stack、registers
  • Process 是沒有也不需要 Stack, Process 本身資源( OS 分配的)擁有者而 Thread 是執行者。

Process 是 OS 分配資源的對象
Thread 是 OS 分配 CPU 時間的對象

WSGI

WSGI,全稱 Web Server Gateway Interface,或者 Python Web Server Gateway Interface ,是為 Python 語言定義的 Web 伺服器和 Web 應用程式或框架之間的一種簡單而通用的介面,也就是幫助協議之間進行轉換。

WSGI 是作為 Web 伺服器與 Web 應用程式或應用框架之間的一種低階別的介面,以提升可移植 Web 應用開發的共同點。WSGI 是基於現存的 CGI 標準而設計的。

很多框架都自帶了 WSGI server ,比如 Flask,webpy,Django、CherryPy等等。當然效能都不好,自帶的 web server 更多的是測試用途,釋出時則使用生產環境的 WSGI server或者是聯合 nginx 做 uwsgi 。

也就是說,WSGI就像是一座橋樑,一邊連著web伺服器,另一邊連著使用者的應用。但是呢,這個橋的功能很弱,有時候還需要別的橋來幫忙才能進行處理。

WSGI定義與協調Python程序與請求之間的接口,常用的WSGI容器有Gunicorn和uWSGI,而Gunicorn更加快捷。

Gunicorn ‘Green Unicorn’ is a Python WSGI HTTP Server for UNIX.

Flask

Flask是一個基於Python的Web開發微框架,借助Web框架,我們就不用關心請求,響應這些底層的實現,而專注於業務的實現~ 而Flask相比於其他框架更加輕量,自由度更高。

Nginx

Nginx 是一個異步框架的Web服務器,我將它部署在Gunicorn前面,通過反向代理連接. 其實不加Nginx也是可以的,但是加上Nginx有更多好處, 例如 靜態文件支持,負載均衡等等。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

前置作業

  • 已經有一台虛擬私人主機(VPS, Virtual Private Server)
  • Ubuntu 16.04
  • 已經有網域並指向到這台主機的IP位址
  • Python3 (不用安裝,Ubnutu已經內建)

Gunicorn配置注意事項

worker視為Process,所以資源是各自獨立的。因此,修改A變數時,並不會影響另外一個worker的變數A。若想同步修改,則只能透過存到資料庫,透過通知或需要的時候進行讀取並修改。否則,一個worker拚到底啊!

當 gunicorn worker type 用 gthread 時,可額外加參數 thread 指定每個 process 能開的 thread 數量,此時 concurrency 的上限為 worker 數量乘以給各 worker 能開的 thread 數量。

worker type 適用場景

  • 當需要穩定的系統時, 用 process 處理請求可以保證一個請求的異常導致程式 crash 不會影響到其他請求。
  • 當 web 服務內大部分都是 cpu 運算時,用 thread 可以提供不錯的效能。
  • 當 web 服務內大部分都是 io 時,用非同步 io 可以達到極高的 concurrency 數量。

參考

WSGI詳解
部署簡單介紹 I
部署簡單介紹 II
Gunicorn配置
Program/Process/Thread 差異
淺談 Gunicorn 各個 worker type 適合的情境