引言
Windows下部署Flask应用一直是一个令人头疼的难题,本人经过一天的摸索,总算部署成功。下面是本次探索的记录。同时为了后来者的方便,放出本文档的相关软件工具,免去逐一下载的麻烦:
链接:https://pan.baidu.com/s/1yAR3WIEmXtLxZmx05rwENg
密码: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
到这里下载Python3.6:https://www.python.org/downloads/release/python-366/
安装步骤略,默认装在「C:\Python36」目录。
三、Apache24
3.1 下载
进入 https://www.apachehaus.com/cgi-bin/download.plx 页面下载Apache24,这里是已经编译好的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
之后可以按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 下载
从这里 https://www.lfd.uci.edu/~gohlke/pythonlibs/#mod_wsgi 下载编译好的 mod_wsgi:
这里我们选择最新的「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>
访问「http://127.0.0.1:5000」,可以看到浏览器输入了「Hello World!」。
七、完成
至此,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的处理速度明显提升很高。
参考资料: