消息队列落地里没人愿意明说的取舍
上周去紫东国际创意园的技术沙龙,散会的时候蹲在门口碰到个做电商的后端,手里夹着半根烟,脸拉得老长。
问了才知道,上周年中大促把系统搞崩了。三个核心服务——订单、库存、营销,全是同步串着调,用户点提交订单,要顺着接口链路过完三个服务才能返回结果,流量一上来,线程池直接打满,整个接口集群堵得死死的。
我问他为啥不上消息队列。
他猛吸了一口烟,说去年双11被坑怕了。当时上了RabbitMQ做异步下单,消费端没做好幂等校验,用户点了三次支付,消息重投了三次,真的扣了三笔钱。财务追着他骂了小半个月,从那以后他见了队列就发怵。
消息队列同步异步调用链路对比示意图
之前在雨花软件园碰到个做工业互联网的开发,他们的场景更纠结。车间里的设备告警信号,必须实时传到平台,晚个两秒可能设备就因为过热烧了。一开始为了扛住设备上报的海量运行数据,用Kafka开了批量发送,攒够100条消息才打一个网络包。结果一次园区网络抖动,攒的二十条告警消息延迟了三秒才送到平台,值班的运维差点没吓死。
最后他们没搞什么复杂的优化,就是把通道拆了。核心告警走低延迟的专属队列,关批量发送,哪怕吞吐量低一半也没关系;剩下的设备温湿度、运行时长这类非紧急数据,走原来的高吞吐批量通道。
没什么高大上的技巧。
就是取舍。

开源消息队列集群日常运维成本对比表
之前有个朋友在江北的创业公司,一开始为了“技术先进”上了Pulsar,折腾了三个月,碰到一次分区重平衡的问题,翻遍了官方文档都没找到解决方案,整个集群卡了快两个小时,差点把核心业务搞挂。最后咬咬牙切回了RabbitMQ,半天就迁完了,后来大促扛了三倍流量,连个告警都没弹过。
说真的,没必要。
你又不是要做亿级用户的社交平台,犯不上为了那点理论上的性能优势,给自己挖运维的坑。选型的核心从来不是谁的参数好,是你的团队能不能hold住出问题的时候。
别把消息队列当银弹
真不是他个例。 太多人对消息队列的认知停留在“加了就能扛住大流量”的层面,根本没算过要付的代价。你把原来的同步调用改成异步,用户点完提交订单,订单系统先把本地事务写完,把消息丢进队列,剩下的扣库存、发优惠券、加积分的逻辑,全交给下游服务慢慢消费。听起来很顺,响应时间一下子从几百毫秒降到几十毫秒。 但麻烦在于,链路一旦拆成异步,原来同步调用里天然的一致性约束就没了。消息丢了怎么办?消费端处理失败了怎么办?下游服务临时挂了,消息堆在队列里攒了几个小时,等服务恢复的时候,用户早就因为等不及退单走了。 你省下来的那几十毫秒接口响应时间,最后全得补到排查一致性问题的时间上。选型的时候别盯着吞吐量死磕
很多人选消息队列的时候,上来就把各家的性能测试报告翻个遍,谁一秒能扛十万条消息,谁的端到端延迟能压到几毫秒,比来比去选个参数最猛的。 说白了,90%的中小团队,业务量根本到不了那个量级。你一个做本地社区的平台,一天的消息量撑死了几百万,哪怕是最基础的开源队列,都能轻轻松松跑满,根本摸不到性能天花板。 真正的成本在运维。你一开始选了个需要三个人专门盯的集群,结果团队就两个写业务的后端,平时赶需求都忙得连轴转,哪有空天天盯队列的磁盘使用率、分区同步状态、副本延迟?