部署在Heroku上的Slack机器人问题:多并行对话异常
解决Heroku上Slack机器人并行对话问题的方案
1. 调整Gunicorn进程配置
默认Gunicorn会启动多个worker进程,即使单个dyno,多进程也会并行处理Slack请求,直接导致对话逻辑混乱。修改你的Procfile,强制使用单进程单线程:
web: gunicorn --workers=1 --threads=1 app:app
此配置会让所有请求被串行处理,从进程层面避免多实例同时执行对话逻辑。
2. 应用层面添加全局锁
即使单进程单线程,也可能因Slack重试机制或并发请求触发并行处理行为。在对话处理逻辑外层添加全局锁,确保同一时间只有一个对话在执行:
import threading # 全局对话锁 conversation_lock = threading.Lock() def process_slack_message(message): with conversation_lock: # 执行你的多阶段对话逻辑 if message.get("type") == "challenge": handle_challenge(message) elif message.get("content") == "keywords": handle_keywords(message) # 其他对话阶段处理...
with语句会自动完成锁的获取与释放,确保对话逻辑严格串行执行。
3. 过滤重复的Slack请求
Slack会对未及时响应的请求发起重试,可能导致同一请求被多次处理。可以通过请求头的唯一标识缓存已处理的请求:
processed_requests = set() request_cache_lock = threading.Lock() def handle_slack_request(request): # 生成请求唯一标识 timestamp = request.headers.get("X-Slack-Request-Timestamp") signature = request.headers.get("X-Slack-Signature") request_id = f"{timestamp}_{signature}" with request_cache_lock: if request_id in processed_requests: return "Request already processed", 200 processed_requests.add(request_id) # 处理对话逻辑 message = request.get_json() process_slack_message(message) return "OK", 200
该逻辑能过滤掉重复的重试请求,进一步保障对话流程的串行性。
内容的提问来源于stack exchange,提问作者Macarena GC
相关产品推荐
相关产品推荐

