如何向RabbitMQ Worker发送SIGINT信号实现部署时暂停消费?
Sneaker + RabbitMQ 暂停消费实现方法
针对部署时需要Worker完成当前任务、停止拉取新任务的需求,有两类可落地的操作方式,分别适配不同场景:
方案1:Sneaker 原生CLI信号控制(生产环境优先推荐)
Sneaker本身内置了优雅停机的信号处理逻辑,不需要修改RabbitMQ配置,操作最简单也最不容易出错:
- 给Sneaker主进程发送
USR1信号后,进程会立刻停止向RabbitMQ拉取新消息,等待所有正在执行的Worker任务全部完成后自动退出,完全匹配部署场景的要求 - 具体操作命令:先找到Sneaker运行时的pid文件(默认路径为项目目录下的
tmp/pids/sneaker.pid,如果启动时自定义了pid路径就替换为实际路径),执行命令:kill -USR1 $(cat tmp/pids/sneaker.pid) - 注意不要误用
TERM、INT信号,这两个信号会强制中断正在运行的任务,可能造成消息丢失、任务状态异常。
方案2:RabbitMQ 侧管控操作(适合多实例批量管控场景)
如果需要批量管控多个Sneaker实例,或者没有服务器上Sneaker进程的操作权限,可以通过RabbitMQ的CLI或者管理界面实现:
2.1 RabbitMQ 命令行操作
- 先执行命令列出指定vhost下的所有消费者,筛选出Sneaker进程对应的
consumer_tag:rabbitmqctl list_consumers -p <你的业务vhost名称> - 找到对应消费队列的Sneaker消费者标签后,执行basic_cancel指令通知消费者停止拉取新消息:
这个操作不会断开现有连接,也不会中断正在执行的任务,Sneaker收到cancel通知后就不会再拉取新消息。rabbitmqctl basic_cancel -p <你的业务vhost名称> <对应consumer_tag> - 注意不要直接删除连接、删除队列,会导致未确认的消息被重新入队,引发重复消费问题。
2.2 RabbitMQ 管理界面操作
- 登录RabbitMQ管理后台(默认端口15672),进入「Connections」页面,通过连接的用户名、客户端属性里的sneaker标识,筛选出Sneaker进程对应的连接
- 点进连接详情后切换到「Channels」页签,找到绑定目标消费队列的信道,进入消费者详情后点击
Cancel按钮,即可通知对应消费者停止拉取新消息,不会中断正在运行的任务。
实操提示:滚动部署场景优先选Sneaker原生信号方案,不会误影响同vhost下的其他业务服务;如果是临时需要全局暂停某队列消费,再选择RabbitMQ侧操作,操作前务必核对消费者信息,避免误操作。
内容的提问来源于stack exchange,提问作者Kunal Vashist
相关产品推荐
相关产品推荐

