借鸡生蛋后,却遭遇杀鸡取卵
2024-02-12 11:01:46
曾经有个远房表弟跟我说:“学技术就像养孩子,你得从小养起”。彼时,我对此嗤之以鼻,自认为天赋异禀,区区技术,不过就是动动手指的事情,何须跟养孩子那样费力费时。
然而,一个颇为奇葩的线上问题,彻底地打破了我天真的想法。
借鸡生蛋,一石二鸟
公司上线了一个刷新用户 token 的功能,说白了就是我们经常在 App 中看到的保持在线的功能,只要操作不断,就能一直在线,以此来增强用户体验。
技术选型的时候,一位自称阿里 P8 的前辈说:“要大胆,要创新,别总用老掉牙的方案,我告诉你一个好办法,用消息队列,把刷新 token 的动作丢到消息队列里,用一个消费者一直监听并执行刷新 token 的动作,保证实时性。”
不得不说,这样的方案确实有新意,既能保证实时性,又能解耦各个业务模块。高人,果然是高人。于是,便决定采纳。
方案确定,接下来就是着手开发了。
因为涉及到消息队列的使用,所以需要新建一个项目,添加必要的依赖,编写相关的代码。折腾了大半天才终于把项目搭建完成,然后就可以愉快地编码了。
消息生产者的代码实现很简单,就是把刷新 token 的动作封装成消息体,然后丢进消息队列里;消费者就更简单了,就是监听消息队列,一旦有消息过来,就立马消费,执行刷新 token 的动作。
不出所料,项目很快就开发完成了。然后,经过简单的测试之后,就上线了。
本来以为万事大吉,可以收工下班了,没想到这才刚刚开始。
杀鸡取卵,祸起萧墙
上线没多久,线上就出现了问题,用户反馈说经常会莫名其妙地掉线,甚至有的时候怎么刷新都没用,必须要退出 App 再重新登录才能恢复正常。
排查了很久,也没找到具体的原因,无奈之下,只好把问题反馈给了阿里 P8。
阿里 P8 远程登录了我们的服务器,查看了日志之后,说:“问题很明显,你们的消息队列积压了大量的消息,消费者处理不过来,导致 token 刷新不及时,用户自然就掉线了。”
“这不可能啊,我们消费者只有一个,处理速度肯定比消息生产者快啊。” 我连忙辩解道。
“那你为什么不看看你的消息队列里有多少消息?” 阿里 P8 反问道。
我打开控制台,一看,好家伙,消息队列里积压了几百万条消息,还在不断地增加。
“这……” 我一时语塞,不知道该说什么。
“你的消费者处理速度不够快,导致消息队列里的消息越来越多,最终把消息队列撑爆了,用户自然就掉线了。” 阿里 P8 继续说道。
“那怎么办?” 我焦急地问道。
“加消费者呗。” 阿里 P8 淡淡地说道。
“加消费者?” 我疑惑道。
“对,加消费者,让更多的消费者来处理消息,这样就能保证消息队列里的消息不会积压了。” 阿里 P8 解释道。
“可是,这样的话,不是违背了之前的设计初衷了吗?” 我还是有点犹豫。
“设计初衷是可以变的,只要能解决问题就行。” 阿里 P8 说道。
我半信半疑地按照阿里 P8 的建议,在项目里加了几个消费者,然后重新上线。
果然,问题解决了,用户再也没有反馈掉线的问题了。
后记
经过这次事件,我终于明白了一个道理:技术没有绝对的对与错,只有适合与不适合。有时候,看似很完美的方案,也可能存在着致命的缺陷。所以,在做技术选型的时候,一定要多方面考虑,不要盲目跟风。
同时,也要学会向别人虚心请教,尤其是那些有经验的人。他们可能会给你一些意想不到的建议,帮助你少走很多弯路。