架构师训练营第 1 期 - 大作业 1
设计概述
通达是某上市公司全资投资成立的一家物流快递公司,目前需要开发一套同城快递系统。该系统分为用户端、快递员端、服务端几个部分,可以由用户自助下单,抢单成功的快递员会负责上门完成用户的递送需求。
公司现有开发人员 20 人,系统预计在两个月后上线。
功能概述
用户可以在用户端 APP 自助下单并支付
快递员端 APP 每隔 30 秒上报一次位置信息
用户支付成功后,系统会将订单推送给距离用户 5km 以内的所有快递员
快递员可以抢单,抢到单的快递员将会由系统下发用户的取件地址
系统将得到配单的快递员信息发送给用户,用户可以查看该快递员的位置、联系方式
快递员取件后在快递员端 APP 标注订单状态为已收件
快件运送过程中,用户可以持续查看快递员的位置、联系方式
快递员将快件送达后在快递员端 APP 标注订单状态为已送达
用户可以查询三个月内的历史订单
非功能性需求
系统预计上线后三个月日订单超过 1 万,一年后日订单超过 50 万
支持接入第三方支付
数据使用加密传输
用户单次查询响应时间 <500ms,95% 响应时间 < 1000ms,单机 TPS>20
下单响应时间 <500ms,95% 响应时间 < 1000ms,单机 TPS>20
系统核心可用性目标 99.99%
系统关键用例图
系统整体架构和部署
架构技术分析:
快递员的位置信息是一个近实时数据,并发读写压力较大,使用 MySQL 会严重影响性能,并且位置数据没有必要进行持久化,因此使用 Redis 集群以 KV 方式存储快递员位置,其中 Key 是快递员的 ID,Value 是序列化的位置数据,并且新版的 Redis 已经有 Geo 组件可以直接支持基于位置信息的计算。
订单信息的查询性能同样使用 Redis 缓存进行优化,这一批 Redis 服务器可以与负责位置信息的 Redis 服务器分开部署。
支付服务调用第三方支付接口完成订单支付。
订单服务在下单时会向位置计算服务发送用户的地址,位置计算服务计算出所有距离用户 5km 以内的快递员 ID,并将这些 ID 发送给消息队列,由推送服务拉取后异步通知各快递员。
抢单是一个类似于秒杀的操作,需要在网关和抢单服务侧进行一定的限流措施,直接由抢单服务来处理并发请求,并将真正抢到单的快递员 ID 写入订单中。
用户查询订单信息,使用 Redis 集群进行性能优化。
MySQL 中存储所有的快递员信息(联系方式)、以及近三个月内的所有订单信息,三个月以上的订单迁移至 ElasticSearch 进行离线存储。
下单抢单场景动态模型
业务活动图
服务器时序图
备注:在下单抢单这个场景中,涉及到用户、快递员、系统三个角色,用户提交订单并支付成功后,系统会生成该笔订单并计入数据库,然后调用位置计算服务筛选出快递员,并推送抢单通知;快递员抢单成功后,系统将快递员信息、用户信息更新到订单,并将订单推送给快递员,同时用户端的订单详情也会显示快递员的信息。
订单状态图
备注:考虑订单出现异常的情况,包括支付失败、无法联系上用户取件、配送失败,另外订单还应当有取消和删除状态。
评论