你有没有过这样的经历?点了外卖,App显示“骑手已取餐,正在派送”,可等了十分钟都没动静。其实,背后可能正有一个“消息队列”在默默排队处理你的订单信息。
快递柜和消息队列,其实是一回事
想象一下小区里的智能快递柜。快递员把包裹放进柜子,系统发一条短信给你:“您的快递已到达,请凭码取件。”这个过程,本质上就是一个消息的生产和消费。
在软件世界里,消息队列干的就是类似的事。一个服务把消息扔进去(比如“用户下单了”),另一个服务从里面取出来处理(比如“减库存”)。它们不直接对话,而是通过中间的“柜子”来传递信息。
看看 RabbitMQ 的一小段代码
拿开源消息队列 RabbitMQ 的 Erlang 源码举个例子。它接收消息的核心逻辑长这样:
handle_info({'basic.deliver', Delivery}, State) ->
Message = extract_message(Delivery),
save_to_queue(Message, State#state.queue),
ack_delivery(Delivery),
{noreply, State};
这段代码的意思是:当收到一条新消息时,提取内容,存进内存队列,然后告诉发送方“我收到了”。就像快递柜收到包裹后亮起灯、发短信一样。
Kafka 的存储设计更像超市货架
Kafka 不把消息全放内存,而是写到磁盘的日志文件里。你可以把它想象成超市的货架,商品按顺序摆放,消费者从某个位置开始拿。
它的 Java 源码里有个关键类 KafkaLogReader,读消息时会记录偏移量(offset):
public ByteBufferMessageSet read(long offset, int maxSize) {
FileMessageSet segment = segments.get(offset);
return segment.read(offset, maxSize);
}
这就像你在超市拿货,店员记住你上次取到第几号货架,下次继续从那里开始,不会漏也不会重复。
很多人觉得“源码分析”高深莫测,其实拆开来看,不过是一堆人写的逻辑,解决的是“怎么安全、高效地传消息”这种实际问题。就像快递柜,设计得好,大家都不用挤在门口等。
下次你看到“系统处理中”,不妨想想,可能正有几千条消息在队列里排队,而你的那一条,已经在前往目的地的路上了。