最直接的办法是用两个 redis-cli 终端分别执行 SUBSCRIBE 和 PUBLISH 命令,若订阅端实时收到 message、频道名、内容三行输出,则 Redis 层面通信通畅;否则问题出在连接、认证、网络或频道名拼写上。

怎么确认 Redis 的 PUBSUB 通道真的有消息在传
最直接的办法不是看发没发,而是用两个终端同时连上 Redis,一边发、一边收,中间不经过应用层。很多人卡在“代码里调了 PUBLISH 却没收到”,其实根本没验证底层通不通。
- 新开一个终端执行
redis-cli,输入SUBSCRIBE mychannel(把mychannel换成你实际用的频道名) - 另开一个终端再连一次
redis-cli,执行PUBLISH mychannel "hello" - 如果第一个终端立刻打出
message、mychannel、"hello"三行,说明 Redis 层面通畅;否则问题出在连接、认证、网络或频道名拼写上
redis-cli 的 PUBSUB CHANNELS 和 PUBSUB NUMSUB 能看出什么
这两个命令不告诉你消息内容,但能暴露“谁在线”和“谁掉线了”。很多订阅者进程崩溃或未正确启动,靠它一眼就能定位。
-
PUBSUB CHANNELS列出当前至少有一个订阅者的频道 —— 如果你的频道不在里面,说明没人成功SUBSCRIBE过 -
PUBSUB NUMSUB mychannel返回类似1) "mychannel" 2) (integer) 0:第二个数字是当前订阅数,为 0 就代表没人挂着,哪怕你代码里写了subscribe(),也可能被异常吞掉或没执行到 - 注意:客户端断开后,Redis 不会立刻清理订阅状态,一般几秒内才更新
NUMSUB,别刚关终端就去查
Node.js 用 ioredis 订阅时,为什么 on("message") 从不触发
常见原因是用了同一个 Redis 实例既发又收,或者没处理重连逻辑。ioredis 的订阅必须走专用连接,且默认不自动重连已订阅的频道。
- 别用写命令的 client 去监听:
const sub = new Redis(); sub.subscribe("mychannel");才对;用redisClient.subscribe(...)是错的(除非你明确知道它底层新建了连接) - 重连后不会自动恢复订阅,得监听
connect事件手动再sub.subscribe("mychannel") - 如果启用了 Redis 密码,确保
new Redis({ password: "xxx" })里传了,否则订阅连接会静默失败,NUMSUB显示为 0
Python 用 redis-py 的 pubsub 对象,listen() 阻塞却没输出
这不是 bug,是设计如此:listen() 是个生成器,必须用 for 循环驱动,且首次调用前要先 subscribe(),否则它根本不知道听什么。
- 错误写法:
pubsub.listen()—— 这只是返回生成器对象,没消费 - 正确写法:
pubsub.subscribe('mychannel') for msg in pubsub.listen(): # 必须这样循环 if msg['type'] == 'message': print(msg['data']) - 如果程序跑一会儿就退出,检查是否漏了
time.sleep()或主线程提前结束;listen()不起新线程,它依赖当前线程活着
调试发布订阅,最难的往往不是语法,而是假设“我已经连上了”“频道名肯定对”“客户端一定在线”。多花 30 秒用 redis-cli 直连验证,比翻半天日志快得多。









