Python 将自定义信号处理程序与gunicorn一起使用

Python 将自定义信号处理程序与gunicorn一起使用,python,flask,signals,gunicorn,Python,Flask,Signals,Gunicorn,我有一个带有自定义信号处理程序的Flask应用程序,用于在退出之前处理清理任务。使用gunicorn运行应用程序时,gunicorn会在应用程序完成所有清理任务之前终止应用程序。您没有解释自定义信号处理程序的含义,但我不确定您是否应该使用它来捕获进程级事件,如关机。相反,您可以使用标准库中的来钩住SIGTERM信号,如下所示: # app.py - CREATE THIS FILE from flask import Flask from time import sleep, time impo

我有一个带有自定义信号处理程序的Flask应用程序,用于在退出之前处理清理任务。使用gunicorn运行应用程序时,gunicorn会在应用程序完成所有清理任务之前终止应用程序。

您没有解释自定义信号处理程序的含义,但我不确定您是否应该使用它来捕获进程级事件,如关机。相反,您可以使用标准库中的来钩住SIGTERM信号,如下所示:

# app.py - CREATE THIS FILE
from flask import Flask
from time import sleep, time
import signal
import sys

def create_app():
  signal.signal(signal.SIGTERM, my_teardown_handler)
  app = Flask(__name__)

  @app.route('/')
  def home():
    return 'hi'

  return app


def my_teardown_handler(signal, frame):
  """Sleeps for 3 seconds, then creates/updates a file named app-log.txt with the timestamp."""
  sleep(3)
  with open('app-log.txt', 'w') as f:
    msg = ''.join(['The time is: ', str(time())])
    f.write(msg)
  sys.exit(0)


if __name__ == '__main__':
  app = create_app()
  app.run(port=8888)


# wsgi.py - CREATE THIS FILE, in same folder as app.py
import os
import sys
from werkzeug.wsgi import DispatcherMiddleware
from werkzeug.exceptions import NotFound

from app import create_app
app = DispatcherMiddleware(create_app())
$ kill -s TERM [PROCESS ID OF GUNICORN PROCESS / $(ps ax | grep gunicorn | head -n 1 | awk '{print $1}')]
[program:my-app]
command = /path/to/gunicorn [RUNTIME FLAGS]
stopsignal = TERM
...
假设您有一个安装了Flask和Gunicorn的虚拟环境,那么您应该能够使用Gunicorn启动应用程序:

$ gunicorn --bind 127.0.0.1:8888 --log-level debug wsgi:app
接下来,在单独的终端中,您可以向应用程序发送术语信号,如下所示:

# app.py - CREATE THIS FILE
from flask import Flask
from time import sleep, time
import signal
import sys

def create_app():
  signal.signal(signal.SIGTERM, my_teardown_handler)
  app = Flask(__name__)

  @app.route('/')
  def home():
    return 'hi'

  return app


def my_teardown_handler(signal, frame):
  """Sleeps for 3 seconds, then creates/updates a file named app-log.txt with the timestamp."""
  sleep(3)
  with open('app-log.txt', 'w') as f:
    msg = ''.join(['The time is: ', str(time())])
    f.write(msg)
  sys.exit(0)


if __name__ == '__main__':
  app = create_app()
  app.run(port=8888)


# wsgi.py - CREATE THIS FILE, in same folder as app.py
import os
import sys
from werkzeug.wsgi import DispatcherMiddleware
from werkzeug.exceptions import NotFound

from app import create_app
app = DispatcherMiddleware(create_app())
$ kill -s TERM [PROCESS ID OF GUNICORN PROCESS / $(ps ax | grep gunicorn | head -n 1 | awk '{print $1}')]
[program:my-app]
command = /path/to/gunicorn [RUNTIME FLAGS]
stopsignal = TERM
...
为了观察结果,您应该注意到,运行
kill
命令时,
app log.txt
文件的内容会在三秒钟延迟后更新。您甚至可以在此目录中生成第三个终端窗口,并运行
watch-n1“cat app log.txt”
以观察此文件是否实时更新,同时在启动应用程序和发送术语信号之间循环

至于将其绑定到生产中,我知道要指定
停止信号
,如下所示:

# app.py - CREATE THIS FILE
from flask import Flask
from time import sleep, time
import signal
import sys

def create_app():
  signal.signal(signal.SIGTERM, my_teardown_handler)
  app = Flask(__name__)

  @app.route('/')
  def home():
    return 'hi'

  return app


def my_teardown_handler(signal, frame):
  """Sleeps for 3 seconds, then creates/updates a file named app-log.txt with the timestamp."""
  sleep(3)
  with open('app-log.txt', 'w') as f:
    msg = ''.join(['The time is: ', str(time())])
    f.write(msg)
  sys.exit(0)


if __name__ == '__main__':
  app = create_app()
  app.run(port=8888)


# wsgi.py - CREATE THIS FILE, in same folder as app.py
import os
import sys
from werkzeug.wsgi import DispatcherMiddleware
from werkzeug.exceptions import NotFound

from app import create_app
app = DispatcherMiddleware(create_app())
$ kill -s TERM [PROCESS ID OF GUNICORN PROCESS / $(ps ax | grep gunicorn | head -n 1 | awk '{print $1}')]
[program:my-app]
command = /path/to/gunicorn [RUNTIME FLAGS]
stopsignal = TERM
...

但这是一个与确保应用程序的清理任务完全执行的原始问题不同的主题。

我应该更清楚地回答我的问题。我正在使用信号模块,但是gunicorn在我的所有清理任务完成之前关闭了应用程序。嗯,关于这些清理任务的一些信息如何?我们应该知道什么?另外,你如何运行/停止Gunicorn?你试图捕捉到哪种信号?