Google Pub/Sub订阅者运行数日后停止接收消息求助
解决Google Pub/Sub订阅者停止接收GCS通知的问题
我之前维护类似的Python脚本时也碰到过一模一样的情况,折腾了好几天才找到原因。结合Pub/Sub的特性和Python客户端的常见坑,给你梳理几个最可能的原因和对应的解决思路:
1. 流量控制导致的拉取阻塞
这是最常见的原因——如果你的消息处理线程速度跟不上Pub/Sub推送的速度,客户端的本地消息缓冲区会被填满,触发流量控制机制,订阅者就会暂停拉取新消息。
解决办法:
调整订阅者的流量控制参数,允许更多的消息积压或者允许临时超额:
from google.cloud import pubsub_v1 subscriber = pubsub_v1.SubscriberClient() subscription_path = subscriber.subscription_path("你的项目ID", "你的订阅ID") # 增大允许的本地消息数量,同时允许临时超额 flow_control = pubsub_v1.types.FlowControl( max_messages=2000, # 根据你的处理能力调整 allow_excess_messages=True ) future = subscriber.subscribe(subscription_path, callback=callback_fun, flow_control=flow_control)
另外,一定要监控你的消息队列长度,如果队列持续增长,说明处理逻辑需要优化(比如并行处理、减少IO耗时)。
2. 后台线程被阻塞或挂死
Python的GIL(全局解释器锁)会限制多线程的执行,如果你的消息处理线程是CPU密集型任务,或者出现了死锁、无限阻塞(比如读取GCS文件时没设置超时),会抢占Pub/Sub客户端后台线程的执行时间,导致客户端无法和服务器保持心跳,最终停止接收消息。
解决办法:
- 给所有IO操作(比如GCS文件读取、数据库操作)设置超时时间,避免线程无限挂起;
- 如果是CPU密集型任务,改用多进程处理(比如用
multiprocessing模块),绕过GIL的限制; - 添加日志监控,记录每个消息的处理时长,快速定位阻塞点。
3. 客户端重连机制失效
旧版本的google-cloud-pubsub库可能存在重连bug,当网络临时波动后,客户端无法自动重新建立连接,看起来就像停止接收消息了。
解决办法:
- 升级到最新版本的客户端库:
pip install --upgrade google-cloud-pubsub - 给订阅者的future添加异常监控,一旦订阅终止就自动重启:
def run_subscriber(): subscriber = pubsub_v1.SubscriberClient() subscription_path = subscriber.subscription_path("你的项目ID", "你的订阅ID") future = subscriber.subscribe(subscription_path, callback=callback_fun) try: future.result() except Exception as e: print(f"订阅异常中断: {str(e)}") subscriber.close() # 自动重启订阅 run_subscriber() if __name__ == "__main__": run_subscriber()
4. 消息确认逻辑异常
虽然你说callback_fun只负责把消息加入队列,但如果callback抛出了未捕获的异常,Pub/Sub客户端会自动触发nack,消息会重新投递。如果大量消息反复nack,可能会触发服务器的限流机制,暂时停止推送。
解决办法:
在callback里添加异常捕获,确保即使加队列失败也能正常ack:
def callback_fun(message): try: # 把消息加入队列的逻辑 message_queue.put(message.data) # 手动确认消息(如果不是自动ack的话) message.ack() except Exception as e: print(f"处理消息失败: {str(e)}") # 可以选择nack让消息重新投递,或者直接ack避免死循环 message.nack()
内容的提问来源于stack exchange,提问作者mrtksy
相关产品推荐
相关产品推荐

