1. 程式人生 > >使用Apache24在Windows下部署Flask(附帶相關軟體工具)

使用Apache24在Windows下部署Flask(附帶相關軟體工具)

引言

Windows下部署Flask應用一直是一個令人頭疼的難題,本人經過一天的摸索,總算部署成功。下面是本次探索的記錄。同時為了後來者的方便,放出本文件的相關軟體工具,免去逐一下載的麻煩:

密碼:0i7g

一、環境

  • Windows 10 x64(理論上Win7+都沒問題)
  • Apache24 x64(Apache22可能會有相容問題)
  • Python 3.6.6 x64(Python 2.7、3.4、3.5及其他版本未測試,不能保證相容)
    • Flask 1.0.2

注意,一定要統一軟體的位數,確定使用64位軟體則全部統一用64位。最好就是按照Windows的位數來選擇軟體。

二、安裝Python3.6

安裝步驟略,預設裝在「C:\Python36」目錄。

三、Apache24

3.1 下載

Apache24下載

這裡選擇「Apache 2.4.35 x64」版本。

下載後放到D盤直接解壓,生成目錄「D:\Apache24」,然後開始修改配置。

3.2 修改配置

第一處:修改「SRVROOT」

如果是放在某個盤的主目錄下,則不需要修改,比如本例我們放在了「D:\Apache24」。
如果是「D:\path\to\dir\Apache24」,則需要修改 Apache24\conf\httpd.conf 的 SRVROOT

#Define SRVROOT "/Apache24"
Define SRVROOT "D:\path\to\dir\Apache24"

第二處:修改監聽埠

找到下面語句

#Listen 12.34.56.78:80  
Listen 80

因為Flask預設監聽5000埠,所以增加5000埠,也可按需新增。

#Listen 12.34.56.78:80  
Listen 80
Listen 5000
Listen 8080

第三處:解決443埠被佔用

如果提示443埠被佔用了

> .\bin\httpd.exe
(OS 10048)通常每個套接字地址(協議/網路地址/)只允許使用一次。  : AH00072: make_sock: could not bind to address [::]:443
(OS 10048)通常每個套接字地址(協議/網路地址/)只允許使用一次。  : AH00072: make_sock: could not bind to address 0.
0.0.0:443 AH00451: no listening sockets available, shutting down AH00015: Unable to open logs

開啟httpd.conf,Ctrl+F找到載入 ssl_module 的那一行,把這一行在開頭加#號註釋掉就好了:

LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
#LoadModule speling_module modules/mod_speling.so
# 下面這一行註釋掉
#LoadModule ssl_module modules/mod_ssl.so

3.3 啟動

修改好以上三處後,Win+R開啟執行,輸入PowerShell並啟動,切換到Apache目錄,然後啟動 http.exe,如果沒有任何報錯,繼續開啟瀏覽器訪問「http://127.0.0.1」,看到下面內容說明啟動成功。

cd D:\Apache24
.\bin\httpd.exe

index

之後可以按Ctrl+C退出。

3.4 把Apache註冊為Windows服務

為了下面步驟方便除錯,我們把httpd註冊為Windows服務,以管理員方式啟動PowerShell

PS C:\WINDOWS\system32> cd  D:\Apache24\bin
PS D:\Apache24\bin> .\httpd.exe -k install
Installing the 'Apache2.4' service
The 'Apache2.4' service is successfully installed.
Testing httpd.conf....
Errors reported here must be corrected before the service can be started.

輸入以上命令即可完成註冊。

然後資源管理器進入「D:\Apache24\bin」,找到「ApacheMonitor.exe」雙擊執行,看右下角找到對應的圖示,右鍵彈出下面的選項,選擇第一個「OpenApache Monitor」。

在這裡插入圖片描述

彈出:

在這裡插入圖片描述

以後我們每次重啟Apache就不需要輸入命令了。

四、安裝mod_wsgi

4.1 下載

在這裡插入圖片描述

這裡我們選擇最新的「mod_wsgi‑4.6.4+ap24vc14‑cp36‑cp36m‑win_amd64.whl」
下載好後隨便放到某個資料夾,然後用pip安裝,「/path/to/」為相關路徑。

pip3 install "/path/to/mod_wsgi-4.6.4+ap24vc14-cp36-cp36m-win_amd64.whl"
Processing /path/to/mod_wsgi-4.6.4+ap24vc14-cp36-cp36m-win_amd64.whl
Installing collected packages: mod-wsgi
Successfully installed mod-wsgi-4.6.4+ap24vc14

pip安裝成功後,輸入命令mod_wsgi-express module-config

> mod_wsgi-express module-config
LoadFile "c:/python36/python36.dll"
LoadModule wsgi_module "c:/python36/lib/site-packages/mod_wsgi/server/mod_wsgi.cp36-win_amd64.pyd"
WSGIPythonHome "c:/python36"

之後會打印出「LoadModule wsgi_module “c:/python36/lib/site-packages/mod_wsgi/server/mod_wsgi.cp36-win_amd64.pyd”」這一條資訊,把這一條資訊拷貝到 http.conf 中,放在其他 loadmodule 之後(大約185行)。

重新啟動Apache,沒有報錯則說明 mod_wsgi 模組載入成功了。

五、Flask

5.1 一個最簡單的Flask

下面先用一個最簡單的Flask應用測試,新建「hello.py」,拷貝下面程式碼:

# hello.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return 'Hello World!'
    
if __name__ == '__main__':
    app.run()

5.2 編寫給apache用的WSGI檔案

在同級目錄下新建「apache_wsgi.py」,拷貝下面程式碼:

import os
import sys

curr_dir = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, curr_dir)

from hello import app

application = app

至此一個簡單的Flask的WSGI配置完成了。可以跳到「配置站點」小節,下面的小節則是額外內容。

5.3 虛擬環境(可選)

如果需要虛擬環境,可以在from hello import app前新增下面程式碼

activate_this = '/path/to/env/bin/activate_this.py'
with open(activate_this) as file_:
    exec(file_.read(), dict(__file__=activate_this))

5.4 一份完整的示例(可選)

基於Flask 1.0.2 和pipenv。假設虛擬環境目錄在Flask專案目錄的「.venv」資料夾裡。

import os
import sys

curr_dir = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, curr_dir)

# 字串前面加r,表示禁止反斜槓轉義
activate_this = curr_dir + r"\.venv\Scripts\activate_this.py"

with open(activate_this) as file_:
    exec(file_.read(), dict(__file__=activate_this))

# 載入.env環境變數
from flask.cli import load_dotenv
load_dotenv()

from appimport create_app

app = create_app("production")
application = app

if __name__ == '__main__':
    application.run()

六、配置站點

開啟Apache的 conf/httpd.conf,在末尾處新增:

<VirtualHost *:5000>
    ServerName example.com
    WSGIScriptAlias / "/path/to/dir/apache_wsgi.py"
    <Directory "/path/to/dir">
        WSGIScriptReloading On
        Require all granted
    </Directory>
</VirtualHost>

七、完成

至此,Windows下使用Apache24部署Flask成功!

八、壓力測試

下面簡單使用ab指令進行壓力測試,PowerShell進入「D:\Apache24\bin」資料夾,輸入:

 .\ab.exe -n 20000 -c 200 http://127.0.0.1:5000/

200併發,傳送2W次請求。

Server Software:        Apache/2.4.35
Server Hostname:        127.0.0.1
Server Port:            5000

Document Path:          /
Document Length:        12 bytes

Concurrency Level:      200
Time taken for tests:   6.801 seconds
Complete requests:      20000
Failed requests:        0
Total transferred:      4080000 bytes
HTML transferred:       240000 bytes
Requests per second:    2940.75 [#/sec] (mean)
Time per request:       68.010 [ms] (mean)
Time per request:       0.340 [ms] (mean, across all concurrent requests)
Transfer rate:          585.85 [Kbytes/sec] received

每秒處理請求(Requests per second)能大約達到3000次/秒。如果是原生的Flask應用呢?

Server Software:        Werkzeug/0.14.1
Server Hostname:        127.0.0.1
Server Port:            5000

Document Path:          /
Document Length:        12 bytes

Concurrency Level:      200
Time taken for tests:   73.696 seconds
Complete requests:      20000
Failed requests:        0
Total transferred:      3320000 bytes
HTML transferred:       240000 bytes
Requests per second:    271.39 [#/sec] (mean)
Time per request:       736.960 [ms] (mean)
Time per request:       3.685 [ms] (mean, across all concurrent requests)
Transfer rate:          43.99 [Kbytes/sec] received

每秒處理請求(Requests per second)大約是271次/秒

由此可見,使用Apache24部署Flask,Flask的處理速度明顯提升很高。

參考資料: