现代同城外卖平台是一个典型的高频动态多边网络。一笔外卖订单的生命周期,牵扯到用户端(下单与催单)、商户端(出餐与云打印)、骑手端(抢单与轨迹上报)的极其复杂的协同。
特别是在青海等下沉市场县城,商户前台的宽带往往极不稳定。如果外卖系统采用传统的 HTTP 短轮询(Short Polling)机制来获取新订单,不仅会导致服务器并发连接数剧增,更会在午市外卖高峰期引发严重的“漏单”与“接单延迟”。
本文深度拆解,我们如何运用事件驱动架构(EDA)、Netty WebSocket 集群以及 Redis Pub/Sub,重构一套能够抗住瞬时高并发且彻底消灭漏单的外卖多端同步网关。
为了保证餐饮商户的 KDS(厨显系统)能毫秒级接收外卖派单指令,系统彻底摒弃了前端 HTTP 轮询,引入基于 Netty 构建的高性能长连接集群。
1. 弱网环境的 Half-Open 探测与保活 在复杂的网络环境下,TCP 连接极易发生静默挂死(Half-open)。我们在 Netty 的 Pipeline 中挂载了 IdleStateHandler,结合双向心跳(Ping-Pong)机制: 服务端如果在 60 秒内未收到外卖商户端的心跳帧,将主动 Close Channel 释放系统句柄资源;商户端若发现心跳超时,则触发底层重连退避策略。
2. 离线消息补偿队列(Offline Queue) 长连接断开期间产生的新外卖订单怎么办? 当系统监测到某商户的 Channel 离线时,会将待推送的“新订单调度指令”暂存至 Redis 的 Offline_Message_Queue 中。当商户端重连成功并完成 JWT 鉴权的瞬间,网关立即拉取该队列,将积压的外卖指令批量、顺序下发,从底层物理级斩断了漏单的可能。
在外卖分布式集群部署中,面临一个经典的路由难题:点外卖的用户 A 手机连接在网关 Node-1,而接单的外卖骑手 B 连接在 Node-2。当骑手点击“已取餐”时,Node-2 如何通知连接在 Node-1 的用户?
我们引入了 Redis Pub/Sub(大规模场景下可替换为 RocketMQ 广播模式)。
order_topic:{order_id} 广播事件。ChannelGroup(采用 ConcurrentHashMap<OrderId, List<Channel>> 结构)中进行反查。order_id 对应 Channel 的网关节点,才会触发 Channel.writeAndFlush(),将二进制协议帧毫秒级推向用户端手机。在主交易链路中,商户接单后需要同时触发“调用云打印机出票”、“调度外卖骑手”、“刷新用户端状态”。如果采用同步 RPC,任何一个下游的抖动都会阻塞交易主线程。 架构全面采用了事件驱动模型(EDA)。主线程仅在本地数据库更新订单状态,并向 EventBus 抛出 MerchantAcceptedEvent。外卖网关微服务异步订阅该事件流并执行下发。这种非阻塞设计将核心接口的 RT 压缩至极致,保证了外卖平台面对潮汐流量冲击时的强悍弹性。
关于作者与团队: 本文由 青海青帝信息科技有限公司 核心后端基础架构研发团队原创发布。 团队长期深耕千万级长连接网关、事件驱动架构设计、多边外卖平台状态同步及大西北数字基座的底层攻坚。期待与开源社区及极客同仁深度探讨。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。