![[Bug]: Continuous False-Positive Slack Alerts for LLM Hanging Requests](https://www.chat-gpts.plus/wp-content/uploads/2026/06/27855-3aabe441.jpg)
[Bug]: Continuous False-Positive Slack Alerts for LLM Hanging Requests
快速结论:这个报错通常发生在 LiteLLM Proxy 以多 worker 模式(–num_workers > 1)部署时,Slack 持续收到 llm_requests_hanging 错误告警,但实际请求响应时间远低于 600 秒阈值。优先排查 worker 数量配置和缓存一致性。
问题场景
用户在使用 LiteLLM Proxy 部署在 AWS ECS 上,配置了 Slack 告警,并设置了 request_hanging_alerting_threshold 为 600 秒。告警持续报告多个模型(如 gemini-3-pro-preview、azure/gpt-5.1)的请求“挂起超过 600 秒”,但实际日志显示这些请求的最大响应时间(max_time_diff_seconds)均低于 600 秒,例如 gemini-3-pro-preview 为 334 秒,azure/gpt-5.1 为 205 秒。
报错原文
Alert type: llm_requests_hanging (Digest) Level: Medium
Start: 2026-05-13 14:51:55 End: 2026-05-13 14:51:55
Count: 1
Message: Requests are hanging - 600s+ request time
Request Model: gemini-3-pro-preview API Base: None Key Alias: Team Alias:
Alert type: llm_requests_hanging (Digest) Level: Medium
Start: 2026-05-13 14:51:55 End: 2026-05-13 14:51:55
Count: 2
Message: Requests are hanging - 600s+ request time
Request Model: azure/gpt-5.1 API Base: None Key Alias: Team Alias:
原因分析
存在两个独立的缺陷,共同导致持续误报:
- 缺陷 1:缺少最小请求存活时间检查。 后台 hanging request 检查循环在启动时立即执行 send_alerts_for_hanging_requests(),没有初始延迟(await asyncio.sleep(alerting_threshold))。请求刚被加入 hanging_request_cache 就会触发检查,此时请求实际存在时间极短,但被误判为“挂起”。后续检查每 alerting_threshold / 2 秒执行一次,导致低于阈值的请求也被反复告警。
- 缺陷 2:request_status 缓存使用 local_only=True。 当 LiteLLM 以多 worker 模式运行时,每个 worker 进程拥有独立的 in-memory 缓存。处理 LLM 响应的 worker 将 request_status 写入自己的缓存,而运行后台检查的 worker 读取自己的缓存——永远看不到其他 worker 设置的状态。结果:所有由其他 worker 处理的请求在检查 worker 看来都永久“挂起”,直到缓存过期(alerting_threshold + 60s)。
两个缺陷叠加:多 worker 模式下,非检查 worker 处理的每个请求都会在第一次循环迭代(缺陷1)和后续每 alerting_threshold / 2 秒(缺陷2)产生误报。告警中 start_time 和 end_time 相同,是因为同一轮循环中所有告警共享同一个时间戳。
环境排查
- 确认 LiteLLM Proxy 运行时的 worker 数量:是否使用了 –num_workers > 1
- 检查 request_hanging_alerting_threshold 配置值(默认 600 秒)
- 确认 alert_type_config 下 llm_requests_hanging 的 digest 和 digest_interval 配置
- 确认是否使用共享 Redis 缓存(internal_usage_cache)
解决步骤
- (可优先尝试)修复缺陷2: 在
ProxyLogging.update_request_status中将local_only=True移除,确保 request_status 写入共享 Redis 缓存,所有 worker 可以互相读取。代码如下:await self.internal_usage_cache.async_set_cache( key="request_status:{}".format(litellm_call_id), value=status, local_only=False, # 改为 False,写入共享缓存 ttl=alerting_threshold, litellm_parent_otel_span=None, ) - (可优先尝试)修复缺陷1: 在
AlertingHangingRequestCheck.check_for_hanging_requests中添加初始延迟:async def check_for_hanging_requests(self): await asyncio.sleep(self.slack_alerting_object.alerting_threshold) # 添加初始延迟 while True: verbose_proxy_logger.debug("Checking for hanging requests....") await self.send_alerts_for_hanging_requests() await asyncio.sleep(self.slack_alerting_object.alerting_threshold / 2) - 可选方案: 在
HangingRequestData中添加added_at: float字段,在检查时跳过存活时间低于 alerting_threshold 的请求。
验证方法
修复后,观察 Slack 告警频道:
- 确认不再收到 start_time == end_time 的 llm_requests_hanging 告警
- 对于响应时间低于 600 秒的请求,确认不再产生误报
- 对于真实挂起超过 600 秒的请求,确认仍能收到告警
- 建议在低流量环境或测试集群先验证修复效果



