Kafka、RabbitMQ与Redis在消息模型、性能和适用场景上差异显著:Kafka是分布式提交日志服务,高吞吐、分区有序、支持回溯;RabbitMQ基于AMQP协议,强调可靠路由与业务解耦;Redis Streams提供内存级低延迟队列,轻量但持久化能力弱。

Go 语言本身不提供内置的“语言学习”功能,所谓“在 Go 中进行语言学习”不是语言特性或标准库能力;构建异步消息队列系统则完全可行,但必须明确:Go 标准库没有 MessageQueue 或 Broker 类型,所有成熟方案都依赖外部中间件或第三方库封装。
为什么不能用 channel 直接当生产级消息队列
channel 是 Go 的并发原语,适合协程间短时、内存内通信,但不具备持久化、多进程可见、故障恢复、消费者组、重试、死信等消息队列核心能力。拿 chan string 当 Kafka 用,上线后扛不住重启、丢消息、无法水平扩展。
- 无持久化:进程退出,
channel里未读数据全丢 - 无跨进程通信:不同服务实例之间无法共享
channel - 无 ACK 机制:消费者崩溃时无法回滚未确认消息
- 无监控/管理接口:没法查堆积量、消费延迟、积压速率
该选 Redis 还是 RabbitMQ 或 Kafka
选型取决于吞吐、一致性、运维成本和团队熟悉度,不是语法问题:
-
Redis(用LPUSH/BRPOP或Stream):适合中小规模、低延迟、允许少量丢失的场景;Go 用github.com/go-redis/redis/v9操作,Stream支持消费者组和 ACK,但没 Kafka 的分区重平衡能力 -
RabbitMQ:AMQP 协议,开箱支持死信、TTL、优先级队列;Go 推荐用github.com/streadway/amqp,注意amqp.Connection和amqp.Channel不是线程安全,需复用而非每请求新建 -
Kafka:高吞吐、强顺序、多副本;Go 客户端用github.com/segmentio/kafka-go,注意kafka.Writer默认启用缓冲和重试,但Reader的CommitMessages必须显式调用,否则位点不提交
用 github.com/ThreeDotsLabs/watermill 快速搭骨架
Watermill 是 Go 生态中较成熟的事件驱动框架,屏蔽底层中间件差异,统一抽象 Publisher / Subscriber 接口。它不替代 Kafka,而是帮你少写重复 glue code。
立即学习“go语言免费学习笔记(深入)”;
- 定义消息结构时,字段必须可序列化:避免
func、map[interface{}]interface{}等无法 JSON 编码的类型 - 配置
Redis作为消息中间件时,watermill-redis默认用Pub/Sub,但不保证投递可靠性;改用Stream需手动实现MessageRouter的Ack逻辑 - 消费者启动后,若 handler panic,watermill 默认停止该 consumer 实例——需用
recover()包裹业务逻辑,否则整条消费链路中断
真正卡住人的从来不是 Go 语法,而是消息语义的理解:at-least-once 还是 at-most-once?是否需要幂等?位点存储在哪?这些跟 go run 无关,得看你的 SLA 要求和中间件行为边界。


















