uwsgi master 优雅关机

uwsgi master graceful shutdown

我是运行 uwsgi+flask应用, 该应用程序 运行 作为 k8s pod。

当我部署新的 pod(新版本)时,现有的 pod 收到 SIGTERM。

这会导致 master 在同一时刻停止接受新连接,导致问题的原因是 LB 仍然将请求传递给 pod(多等了几秒钟)。

我希望 master 在停止接受新连接之前等待 30 秒(当收到 SIGTERM 时)但是找不到办法,这可能吗?

我的 uwsgi.ini 文件: [uwsgi]

;https://uwsgi-docs.readthedocs.io/en/latest/HTTP.html
http = :8080
wsgi-file = main.py
callable = wsgi_application
processes = 2
enable-threads = true
master = true
reload-mercy = 30
worker-reload-mercy = 30
log-5xx = true
log-4xx = true
disable-logging = true
stats = 127.0.0.1:1717
stats-http = true
single-interpreter= true
;https://github.com/containous/traefik/issues/615
http-keepalive=true
add-header = Connection: Keep-Alive

使用 uwsgi 似乎无法实现:

https://github.com/unbit/uwsgi/issues/1974

解决方案-(如本 kubernetes 问题所述):

https://github.com/kubernetes/contrib/issues/1140

就是使用prestop hook,比较丑但是有助于实现零宕机:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx
spec:
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        lifecycle:
          preStop:
            exec:
              command: ["/bin/sleep","5"]

模板取自这个答案:

另一种选择是使用 CLI 选项:

--hook-master-start "unix_signal:15 gracefully_kill_them_all"

或在 .ini 文件中:

hook-master-start = "unix_signal:15 gracefully_kill_them_all"

这将在收到 SIGTERM(信号 15)后优雅地终止 worker。

reference见下文。

不过,当我尝试上述操作时,它在 docker 容器中没有按预期工作。相反,您也可以使用 uWSGI 的 Master FIFO 文件。主 FIFO 文件可以指定为:

--master-fifo <filename>

master-fifo = /tmp/master-fifo

然后你可以简单地写一个 q 字符到文件,它会在退出前优雅地关闭你的工人。