windows部署flask+waitress+nginx


记一次在 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

我这里只反代理 getImgvideo 两个 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" '
                      'statusbody_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-IPremote_addr;
            proxy_set_header X-Forwarded-Proto scheme;
            proxy_set_header X-Forwarded-Forproxy_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';
}

访问 aaaa/ 都可以到达;访问 bb 无法到达,访问 bb/ 可以到达。

2.2 开机自启

使用 winsw/winsw 建立 nginx 服务,以开机自启。

官方安装文档:winsw/doc/installation.md,下面的服务配置过程均为引用。

  1. 在其 repo 中下载 exe 可执行文件以及 xml 示例文件,放到与 nginx 执行文件同目录下。如果是 windows 64位则下载 xxxNET4.exe;

  2. 修改上述两个文件名为服务名,这里全部改为 nginxService;

  3. 更改 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>
    
  4. 生成服务:在当前位置打开命令行,执行 .\nginxService.exe install,这样就会在服务中生成。

  5. 如果不再需要,执行 .\nginxService.exe uninstall,卸载服务。

上面配置中 <stopparentprocessfirst>true</stopparentprocessfirst> 推荐使用,否则无法彻底关闭(至少在本人电脑上是这样)。

评论
还没有评论
    发表评论 说点什么