同城快递系统架构
产品需求:
用户通过 app 发起快递下单请求并支付
快递员通过自己的 App 上报自己的地理位置,每 30 秒上报一次
系统收到快递请求后,向距离用户直线距离 5km 内的所有快递员发送通知
快递员需要进行抢单,第一个抢单的快递员得到配单,系统向其发送用户详细地址
快递员到用户处收取快递,并记录到系统中:已收件
快递员将快递送到目的地,并记录到系统中:已送达
说明:预计上线后三个月日单超过 1 万,一年日单超过 50 万
用例图
整体架构部署图
架构技术分析:
快递员的位置信息是一个近实时数据,并发读写压力较大,使用 MySQL 会严重影响性能,并且位置数据没有必要进行持久化,因此使用 Redis 集群以 KV 方式存储快递员位置,其中 Key 是快递员的 ID,Value 是序列化的位置数据,并且新版的 Redis 已经有 Geo 组件可以直接支持基于位置信息的计算。
订单信息的查询性能同样使用 Redis 缓存进行优化,这一批 Redis 服务器可以与负责位置信息的 Redis 服务器分开部署。
支付服务调用第三方支付接口完成订单支付。
订单服务在下单时会向位置计算服务发送用户的地址,位置计算服务计算出所有距离用户 5km 以内的快递员 ID,并将这些 ID 发送给消息队列,由推送服务拉取后异步通知各快递员。
抢单是一个类似于秒杀的操作,需要在网关和抢单服务侧进行一定的限流措施,直接由抢单服务来处理并发请求,并将真正抢到单的快递员 ID 写入订单中。
用户查询订单信息,使用 Redis 集群进行性能优化。
MySQL 中存储所有的快递员信息(联系方式)、以及近三个月内的所有订单信息,三个月以上的订单迁移至 ElasticSearch 进行离线存储。
订单服务活动图
该场景的主要流程如下:
寄件人下单并支付
系统向附近 5km 内的快递员发起抢单
快递员抢单
抢单成功后,系统给寄件人发送寄件码;快递员收到订单详细信息,并上门取件
快递员上门取件后,输入取件码,开始派件;系统给收件人发送收件码
快递员派送成功,输入收件码
订单完成
评论