You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sanic框架before/after_server_stop监听器失效问题求助

问题:Sanic服务器停止时before_server_stop和after_server_stop监听器未触发

运行以下代码时,按下Ctrl+C停止服务器,before_server_stop和after_server_stop两个监听器未生效,控制台仅输出启动日志:

from loguru import logger
from sanic import Sanic

app = Sanic(__name__)

@app.before_server_start
async def start(*_):
    logger.info("Server starting...")

@app.before_server_stop
async def before_server_stop(*_):
    logger.info("Server stopping...")

@app.after_server_stop
async def after_stop(app, loop):
    logger.info("Server shutting down...")

@app.route("/")
async def test(request):
    return text("test")

if __name__ == '__main__':
    try:
        app.run(host='0.0.0.0', port=8000, workers=1)
    except KeyboardInterrupt:
        app.stop()

控制台输出:

2024-09-10 16:45:23.567 | INFO     | __mp_main__:start:20 - Server starting...

解决方法

1. 修复缺失的text函数导入

原代码中调用text("test")但未导入该函数,会导致请求时报错,先补上导入语句:

from sanic.response import text

2. 调整服务器停止的处理逻辑

当指定workers=1时,Sanic会启动多进程模式(主进程+1个worker进程),此时主进程捕获KeyboardInterrupt后调用的app.stop()无法触发worker进程上注册的监听器——因为监听器属于worker进程的app实例,和主进程的app实例是分离的。

有两种可行的修复方式:

方式一:使用单进程模式

去掉workers参数(默认单进程),或者显式指定single_process=True,让服务器运行在单个进程中:

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000)

此时按下Ctrl+C,监听器会正常触发,控制台会输出:

2024-09-10 16:45:23.567 | INFO     | __main__:start:20 - Server starting...
2024-09-10 16:46:00.123 | INFO     | __main__:before_server_stop:24 - Server stopping...
2024-09-10 16:46:00.124 | INFO     | __main__:after_stop:28 - Server shutting down...

方式二:多进程模式下移除手动停止逻辑

如果必须使用多进程,直接移除主进程的try-except块,让Sanic自身处理停止流程——Sanic会自动向所有worker进程发送停止信号,触发对应的监听器:

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000, workers=1)

3. 确认监听器参数正确性

before_server_stop的标准参数签名是async def before_server_stop(app, loop),你的代码中用*_忽略参数是可行的,但如果后续需要使用app或loop对象,需确保正确接收参数。

内容的提问来源于stack exchange,提问作者hpp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 11:05:56