记一次在 windows 下部署 flask。结构为 flask + waitress + nginx。
1. flask
图片与 mpjpeg 服务器,关键代码 routes.py
:
from mjpeg_server import app, redis, logging
from flask import Response
# import sys
# import time
@app.route('/getImg/')
def index():
res = redis.get('mpjpeg_cache')
return Response(res, mimetype="image/jpeg")
def gen():
lastres = b'a'
while True:
# time.sleep(0.3)
# t1 = time.time()
res = redis.get('mpjpeg_cache')
if res and res != lastres:
logging.info('Updated data.')
# logging.info(f'time cost: {time.time() - t1}.')
lastres = res
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + res + b'\r\n\r\n')
@app.route('/video/')
def video():
return Response(
gen(),
mimetype='multipart/x-mixed-replace; boundary=frame')
url 说明:路由的 url 最好加斜杠,否则路由下的视图无法匹配不带斜杠的 url。
完整项目代码:waiting for update
2. WSGI
由于 windows 下不支持 uwsigi、gunicorn 等等,支持的 apache + mod_wsgi
较繁重,此处使用 waitress + nginx,waitress 官方文档:waitress 1.4.4,官方 repo: Pylons/waitress。
简单使用:针对我上面的 flask 程序,新建下面 py 脚本,启动即可完成。
from waitress import serve
from mjpeg_server import app
serve(app, host='0.0.0.0', port=5000)
3. nginx
Windows 版 nginx 官方下载地址:nginx for Windows,此处使用 1.18.0 版本。
下载后为了方便调试,新建两个批处理来 reload 以及停止:
第一个:reload:
REM reload.bat
nginx.exe -s reload
pause
第二个:停止:
REM stop.bat
nginx.exe -s stop
2.1 配置
下载的 nginx 压缩包中不用项可以删除。下面是我删除后的目录:
/mnt/e/nginx-1.18.0
├── [drwxrwxrwx] conf
│ ├── [-rwxrwxrwx] mime.types
│ └── [-rwxrwxrwx] nginx.conf
├── [drwxrwxrwx] html
│ ├── [-rwxrwxrwx] 404.html
│ ├── [-rwxrwxrwx] 50x.html
│ └── [-rwxrwxrwx] index.html
├── [drwxrwxrwx] logs
├── [-rwxrwxrwx] nginx.exe
├── [-rwxrwxrwx] reload.bat
├── [-rwxrwxrwx] stop.bat
└── [drwxrwxrwx] temp
我这里只反代理 getImg 和 video 两个 url,我的配置文件 nginx.conf
:
worker_processes 2;
error_log logs/error.log;
pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
sendfile on;
keepalive_timeout 65;
charset utf-8,gbk;
server {
listen 8080;
server_name localhost;
location = / {
root html;
index index.html;
}
location /JD_detect_img {
charset gbk; # windows 中文编码
alias E:\\JD_detect_img; # 文件路径
autoindex on; # on: 开启文件列表
autoindex_exact_size off; # off:KB, GB,on: byte
autoindex_localtime on; # on: 显示文件修改时间为服务器本地时间
}
error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location ~* /(getImg|video) {
proxy_pass http://127.0.0.1:5000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Port $server_port;
}
}
}
要注意的是,关于在 location 的 path 后斜杠问题,见下例:
location /aa {
add_header Content-Type text/plain;
return 200 'aa';
}
location /bb/ {
add_header Content-Type text/plain;
return 200 'bb';
}
访问 aa 与 aa/ 都可以到达;访问 bb 无法到达,访问 bb/ 可以到达。
2.2 开机自启
使用 winsw/winsw 建立 nginx 服务,以开机自启。
官方安装文档:winsw/doc/installation.md,下面的服务配置过程均为引用。
- 在其 repo 中下载 exe 可执行文件以及 xml 示例文件,放到与 nginx 执行文件同目录下。如果是 windows 64位则下载 xxxNET4.exe;
-
修改上述两个文件名为服务名,这里全部改为 nginxService;
-
更改 nginx.xml 内容,配置文件详细解释winsw/doc/xmlConfigFile.md,此处配置为:
<service> <!-- 配置中 %BASE% 表示 nginxService.exe 的路径 --> <!-- 服务id,应该在服务中唯一不重复 --> <id>nginx</id> <!-- 服务名 --> <name>nginx</name> <!-- 服务描述 --> <description>nginx 服务(powered by WinSW)</description> <!-- 启动 --> <executable>%BASE%\nginx.exe</executable> <!-- 停止 --> <stopexecutable>%BASE%\nginx.exe -s stop</stopexecutable> <!-- 停止时先关闭父进程,在本人电脑不配置此项就无法彻底关闭 --> <stopparentprocessfirst>true</stopparentprocessfirst> <!-- 失败动作:20s 后重启 --> <onfailure action="restart" delay="20 sec"/> <!-- 启动模式:自启动 --> <startmode>Automatic</startmode> <!-- 日志文件目录:logs --> <logpath>%BASE%\logs</logpath> <!-- 日志文件存储方式:以大小切割,10240KB,最多 8 个文件 --> <log mode="roll-by-size"> <sizeThreshold>10240</sizeThreshold> <keepFiles>8</keepFiles> </log> </service>
- 生成服务:在当前位置打开命令行,执行
.\nginxService.exe install
,这样就会在服务中生成。 - 如果不再需要,执行
.\nginxService.exe uninstall
,卸载服务。
上面配置中 <stopparentprocessfirst>true</stopparentprocessfirst>
推荐使用,否则无法彻底关闭(至少在本人电脑上是这样)。
你这还是不支持异步吧
waitress 本身支持异步。我未尝试,上面演示的程序没有配置异步。