Shopify Webhook超时问题:如何先返回200再执行耗时任务?
先返回200再异步处理Shopify Webhook任务的实现方案
针对你遇到的Shopify Webhook超时问题,核心思路是把耗时的example_function放到后台异步执行,让主请求线程立即返回200状态码。以下是两种适合PythonAnywhere环境的实现方式:
方法一:使用Python线程(快速实现,无额外依赖)
这是最简单的方案,直接利用Python标准库的threading模块创建后台线程处理任务:
import threading import json from flask import request # 适配你当前使用的Web框架,这里假设是Flask def example(): if request.method == 'POST': # 先复制请求数据,避免返回响应后请求上下文被销毁导致无法访问 task_data = request.json.copy() # 启动后台线程执行耗时任务,daemon=True确保线程随主进程结束而终止 threading.Thread(target=example_function, args=(task_data,), daemon=True).start() # 立即返回Shopify要求的200响应 return json.dumps({'success': True}), 200, {'ContentType': 'application/json'}
注意事项:
- 请求上下文问题:必须先复制
request.json的数据,因为返回响应后,Web框架(比如Flask)会销毁当前请求的上下文,后续线程再访问request对象会报错。 - 异常日志:在
example_function内部添加完善的日志记录,因为后台线程的异常不会主动抛出到主进程,不记录的话任务失败很难排查。 - 进程重启风险:PythonAnywhere的WSGI进程可能会因为资源限制或配置更新重启,此时未完成的后台线程会被中断。如果任务涉及关键业务(比如订单处理),建议搭配数据持久化(比如先把任务数据存到数据库),避免数据丢失。
方法二:使用任务队列(进阶方案,适合高可靠性需求)
如果对任务可靠性要求高,推荐使用Celery这类专业的任务队列,搭配Redis作为消息中间件(PythonAnywhere支持Redis服务):
步骤1:安装依赖
pip install celery redis
步骤2:配置Celery
# celery_config.py from celery import Celery # 配置Redis作为消息中间件,替换为你的Redis连接信息 app = Celery('shopify_tasks', broker='redis://localhost:6379/0') @app.task def async_example_function(task_data): example_function(task_data)
步骤3:修改Webhook视图函数
import json from flask import request from celery_config import async_example_function def example(): if request.method == 'POST': # 提交任务到Celery队列,立即返回响应 async_example_function.delay(request.json) return json.dumps({'success': True}), 200, {'ContentType': 'application/json'}
步骤4:启动Celery worker
在PythonAnywhere的控制台中运行:
celery -A celery_config worker --loglevel=info
优势:
- 任务持久化:即使Web进程重启,未完成的任务会保存在Redis中,worker恢复后会继续处理。
- 重试机制:可以配置任务失败自动重试,避免因临时故障导致数据丢失。
- 监控与管理:Celery提供了任务监控工具,方便跟踪任务执行状态。
内容的提问来源于stack exchange,提问作者user2097371
相关产品推荐
相关产品推荐

