架构师训练营:通达同城快递架构设计文档
大作业一
背景
通达是某上市公司全资投资成立的一家物流快递公司,主要进行同城快递业务,公司刚刚成立,组建 20 人技术部门,准备两个月后系统开发完成上线,你是后端架构师,请你完成系统顶层架构设计,并组织架构评审会议。
说明: 技术部没技术负责人,由产品负责人兼管(产品负责人为原某互联网大厂的产品总监,研发出身),架构师(你)是技术部最资深的技术人员。
技术方案建议
用户下单请求通过负载均衡服务器分发给下单网关集群
使用消息队列向 5km 内的快递员发送通知,消费者服务器获取的消息内容包括:
用户地址
快递员列表
快递员实时位置缓存在分布式缓存 Redis 中
数据存储使用 MySQL,第一个上线版本不要求做数据分片,但要做主从复制
说明:以上技术方案建议是公司请的外部技术顾问(该顾问是产品负责人的朋友)给出的,具体是否合适请架构师自己定夺
通达同城快递系统架构设计文档
1 设计概述
通达同城快递系统是一个针对同城快递业务量身打造的专业快递系统, 系统从客户手机下单-快递员抢单-联系客户取件-中转-派送从而实现一系列的系统化跟单。打造新型的快递商业模式,让快递在同城范围内安全准时送达是公司的战略核心目标,承担着公司发展并在同城快递领域里成为领军者的目标任务。该系统并且支持开通多城市运行,具有极大的跨地域性发展潜力。
1.1 功能概述
系统主要的功能包括以下8点:
用户通过 app 发起快递下单请求并支付
网页App
Android App
iOS App
快递员通过自己的 App 上报自己的地理位置,每 30 秒上报一次
系统收到快递请求后,向距离用户直线距离 5km 内的所有快递员发送通知
快递员需要进行抢单,第一个抢单的快递员得到配单,系统向其发送用户详细地址
系统将得到的配单的快递员信息发送给用户,用户可以查看快递员的位置以及联系方式
快递员到用户处收取快递,并记录到系统中:已收件
快递员将快递送到目的地,并记录到系统中:已送达
用户可以查询三个月内的历史订单
系统的使用者包括各年龄段的普通用户以及快递员。
系统关键用例图如下:
1.2 非功能性需求
系统未来预计一年用户量达到百五,上线后三个月日单超过 1 万,一年日单超过 50 万
需要支持接入第三方的支付系统或者平台
系统安全性
系统可拦截DDDOS攻击
密码数据散列加密
客户端数据HTTPS加密
外部系统间通信对称加密
响应时间要求
用户单次查询: <= 500ms
用户95%查询: <= 1000ms
查询单机TPS > 100
单次下单: <= 500ms
下单95%: <= 1000ms
下单单机TPS > 30
系统核心功能年可用性目标: 99.99%
2 架构设计重点
2.1 基于领域设计
软件系统设计基于领域驱动设计,划分领域。每一个领域的划分要做到要满足高内聚低耦合,层次分明、边界清晰。在水平方向遵循DDD的四层架构,在垂直方向以聚合为单位划分逻辑边界。通过建设两种不同的中台: “业务中台”和“大数据中台”双中台,为通达企业引入一种新型的,面向未来的,可持续优化和扩展的长效机制,让业务、数据沉淀成服务,提高企业的响应能力。
初始领域划分:
2.2 团队成员划分
因为初期团队成员一共就20人,可以按照技术栈来进行分组, 假设技术部12人
后端组: 负责后端开发,架构,运维
Web组: 前端开发
App组: 手机App开发
2.3 系统可扩展性架构
由于预期一年内系统的并发量会从日1万增长到50万,那么说明系统的的吞吐量要求的增长是50倍,为了让系统具有可扩展性,能够水平伸缩,那么我们在进行数据库设计的时候采取预分区策略,预定义一定数量的分区,比如100个,允许多个逻辑分区对应一个物理节点。在进行缓存设计的时候采用集群设计(Redis)。
2.4 消息中间件
下单和抢单通过消息中间件解耦,由于下单的用户比快递员多,为了平衡两边的处理能力,使用消息中间件来削峰填谷,降低耦合性,提高系统可靠性。高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。我们通过提供消息传递和消息排队模型,它可以在分布式环境下提供应用解耦、弹性伸缩、冗余存储、流量削峰、异步通信、数据同步等等功能,这将是同城系统的一个重要组件
2.5 业务中台+大数据中台
我们打造“业务中台”和“大数据中台”双中台,让业务和市场紧密结合,互相协同发展。“业务中台”通过领域建模和微服务技术落地,“大数据中台”通过数据资产建模和大数据技术落地。“业务中台”主要是针对业务发展,而“大数据中台”主要针对数据资产化,提供数据服务
3 系统部署图与整体设计
系统上线时预计部署20台服务器,需要网关服务器,微服务服务器,负载均衡,分布式缓存,消息队列服务器,消息消费者服务器,Redis内存数据库,数据库服务器等。每个功能模块均采用了高可用,易垂直或者水平扩展的设计,可以随时针对某一模块进行扩容。App的运行环境为容器技术,方便不同环境的迁移。考虑到今后的扩容以及运维,建议从云平台开始架构。
3.1 系统部署图
网关服务主要是用户鉴权,防止攻击,第一个面向用户系统,需要1台服务器
消息队列服务器,负责快速响应用户请求,需要1台服务器。
负责均衡服务器,需要对流量进行均衡到业务服务器,需要2台服务器。
分布式缓存服务器,这是减轻服务器的重要手段,需要1台服务器。
用户微服务,正常在注册、登录才会访问,流量不是很大,需要1台服务器。
订单微服务,大流量入口,用户下单的时候,快递抢单,用户状态等操作频繁,需要2台服务器。
抢单微服务,用户下单成功以后,抢单微服务给附近5km 的快递员发送新订单推送;快递员会抢单,通过抢单微服务,最终确定接单的快递员;需要1台服务器;
位置汇报微服务,需要1台服务器
Redis 内存数据库,记录快递员的最新地理位置信息;需要1台服务器;快递员的位置信息是一个近实时数据,并发读写压力较大,使用MySQL会严重影响性能,并且位置数据没有必要进行持久化,因此使用Redis集群以KV方式存储快递员位置,其中Key是快递员的ID,Value是序列化的位置数据
客服微服务,需要1台服务器
数据采集系统的功能职责为查询用户消费数据,生成统计报表,部署2台服务器,依赖用户系统和订单新系统,实现订单信息和报表统计功能。
数据库系统,业务系统与数据采集服务数据分离,都需要主数据库、重数据库,需要6台服务器。
第三方支付系统为外部系统,支持用户用微信、支付宝、银联等第三方支付充值。这里是订单微服务的一部分。
3.2 下单抢单场景的业务活动图
下单时,用户通过手机app进行下单
系统接收到用户的订单要求之后,创建生成订单,并收取费用
系统根据用户的地址,在<=5km的距离范围内,根据快递员的实时位置进行快递员查找
系统将订单群推送给地理位置符合要求的快递员,抢单开始
快递员抢单成功之后,系统更新订单状态
快递员与用户进行联系,获取取货地址
快递员获取货物,然后进行派送
派送结束之后,快递员更新系统,订单结束
系统更新用户订单状态
3.3 下单抢单业务场景时序图
下单时,用户通过手机app进行下单
系统接收到用户的订单要求之后,创建生成订单,并收取费用
系统根据用户的地址,在<=5km的距离范围内,根据快递员的实时位置进行快递员查找
系统将订单群推送给地理位置符合要求的快递员,抢单开始
快递员抢单成功之后,系统更新订单状态
快递员与用户进行联系,获取取货地址
快递员获取货物,然后进行派送
派送结束之后,快递员更新系统,订单结束
系统更新用户订单状态
3.4 订单状态图
订单有两种状态:
成功 -> 进行支付
取消 -> 系统删除
支付失败或者联系用户失败,均视为订单取消
货物配送有两种状态:
成功 -> 货物配送
失败 -> 配送失败,提交给客服处理
3.5 快递员状态图
快递员有两种状态:
在线,每30秒实时汇报地址
离线, 停止更新地址
4 技术栈选型
5 关键算法方案
5.1 订单位置匹配算法
早期算法: 快递员少的情况下,订单位置匹配采用全部遍历算法,用取件地址经纬度和快递员最新的经纬度,根据欧式距离公式计算直线距离,进行匹配
中期算法:合并快递员位置,用经纬度精度为小数点后两位(距离误差1KM) 做区域定位,先选定区域,后进行区域内快递员位置匹配
后期算法: 在中期区域定位的基础上,根据导航路线距离以及预估上门时间进行匹配
5.2 抢单加锁算法
早期使用Redis实现抢单加锁
中后期使用ZooKeeper实现分布式锁
6 架构服务器成本
按照阿里云通用型ecs.g6.xlarge
, 每台服务器的月费在$52美金,20台服务器的总花费为每月$1000美金。第一年成本在1.5w美金左右,考虑20%左右的浮动成本。
版权声明: 本文为 InfoQ 作者【9527】的原创文章。
原文链接:【http://xie.infoq.cn/article/23664ad94bdaff44bad8389ae】。文章转载请联系作者。
评论