期末大作业 - 同城快递
目 录
1. 文档简介 2
1.1 文档目的 2
1.2 文档范围 2
1.3 定义、缩写词和缩略语 2
1.4 参考资料 2
2. 架构设计目标 2
2.1 关键功能 2
2.2 关键质量属性 2
2.3 业务需求和约束因素 2
3. 架构设计原则 3
3.1 架构设计原则 3
3.2 备选架构设计方案及被否原因 3
3.3 架构设计对后续工作的限制(详设,部署等) 3
4. 系统架构图与整体设计 4
4.1 职责划分与职责确定 4
4.2 关键用例图 5
4.3 业务活动图 7
4.4 系统部署图 8
4.5 服务器时序图 8
4.6 订单状态图 11
5. 关键质量属性的设计原理 11
1. 文档简介
1.1 文档目的
公司要开展同城快递业务,本文档阐述该业务系统的顶层架构,供技术人员参考和讨论。
1.2 文档范围
包括系统总体说明,功能模块及微服务划分,核心业务流程图,系统的非功能约束及相应对策等。
1.3 定义、缩写词和缩略语
1.4 参考资料
2. 架构设计目标
2.1 关键功能
为了实现同城快递业务,需要提供如下功能:
APP用户端:下单,支付(还有评价等)
APP快递员端:定时的位置上报;抢单;记录订单的已收取快递;记录订单的送达目的地
系统推送:收到快递请求,向距离用户5KM内的所有快递员发送通知。
未来的功能:数据分析(日下单量和地理位置分布,接单的平均时间,取件时间,送货时间等,从而可以预测各区域的订单量和增长情况,优化快递员的区域分布和送货路径选择)
2.2 关键质量属性
服务的高可用性,高性能(位置推送的低延迟性和准确性)。
2.3 业务需求和约束因素
系统上线后三个月日单超过一万,假设80%的订单在一天的2小时内下达,峰值再乘以5,那么:QPS = 10000*0.8/7200*5 = 5.55,下单并发量不高。
一年日单超过50万,那么:QPS=5.55*50=277,约为300。下单并发量也一般。
项目一期要求2个月内开发上线,那么主要还是满足高可用和高性能属性,同时希望系统可扩展。
约束因素: 快速计算距离用户XXkm内的所有快递员位置信息并推送;抢单能力也能在快递员数量的快速增长时仍保证及时响应。
3. 架构设计原则
3.1 架构设计原则
按照康威定律,公司的技术人员为20人左右,我们希望拆分的微服务数量比较合适(5-10个),能保证开发和运维的效率。
合适(选用适合该同城快递业务特点的技术方案);
简单(框架是业界比较流行的,各技术组件是相对成熟的,遇到问题方便排查);
可扩展(功能、性能角度都容易扩展)
3.2 备选架构设计方案及被否原因
采用Spring cloud框架,不采用响应式框架,因当前不够成熟;
采用RocketMQ作为异步、解耦、削峰的消息队列方案【异步功能例如向附近的快递员广播某订单下单的消息】,因其Java开发,还有事务型消息【支付类业务】、延迟消息【自动关闭订单】等高级功能,不采用Kafka(功能相对简单)、RabbitMQ(源码不易阅读)等。
采用Redis作为分布式缓存,redis cluster提供了自动分片和数据冗余的方案,可同时满足高并发读写和高可用读写;功能上,它结合其有序队列 ZSET 以及 GEOHASH 编码,实现了空间搜索功能,且拥有极高的运行效率,适合计算附近的人的功能。未来可按城市做数据分片。
采用MySQL作为后台的分布式存储方案,一期做主从复制,未来也能按城市做数据分片的水平扩展。
3.3 架构设计对后续工作的限制(详设,部署等)
任何提升可扩展性的架构设计和详细设计,都应通过架构团队的评审才能引入,以确保性能目标不受重大影响。
4. 系统架构图与整体设计

4.1 职责划分与职责确定
1)APP端:
提供给用户操作的界面和快递员操作的界面,实现与后端服务的交互。
2)API接口层分为两次:
Nginx负责反向代理和负载均衡;
API网关负责鉴权、防刷(用户反复下单)等,采用zuul组件,整合所有业务接口(统一封装返回格式和错误信息)。API Gateway微服务。
3)服务中心:
目前有5个微服务。
登陆服务:用户的注册和登陆,快递员的注册和登陆。前后端交互采用JWT Token。
订单服务:提供订单查询、用户的下单、快递员的抢单、快递员确认已收件、快递员确认已送达 、订单支付等。
位置服务:接收用户下单时的位置上报,快递员的定时的位置上报;用户附近5KM位置的快递员 等。
支付服务:实际处理支付,需要与第三方支付系统交互。
消息服务:指服务器主动向app端推送的消息,目前是向快递员推送附近的新单信息。
4)基础服务中间件
采用Nacos作为注册中心和配置中心,消息队列采用RocketMQ,ELK做日志收集和统计分析(Elasticsearch+Logstash+Kibana),其他组件暂时没有(DB中间件等MySQL未来需分表时再引入)。
5)数据存储
MySQL的主从,存储 用户和快递员的身份和订单相关信息。
Redis: 提供高速的查询服务,例如:存储登陆后的token;存储未关闭的订单的状态信息;存储当前的快递员的位置信息、用户下单的位置信息;提供位置信息的计算服务。
6)部署
希望采购阿里云平台的硬件资源,通过Docker镜像方式做容器自动化部署。
开发人员关注架构图中提到的6个微服务及相应的业务,架构师负责申请资源,搭建好其他中间件
和框架,并做好自动化部署。
4.2 关键用例图
主要业务为用户下单(下单时自动上报位置),此时系统会计算出用户附近5KM的快递员,向他们推送这条下单信息; 此后 用户可以查询订单状态(物流状态和支付状态等)。
快递员进行抢单操作,抢单成功后得到用户详细地址并上门取件(用户支付),快递员更改为已发件状态,送达后更改为已送达。 快递员app在打开状态时,会周期性自动上报位置。

4.3 业务活动图

注意:抢单阶段有且仅有一个业务员能抢单成功;支付分为发件人付款和收件人付款,在用户下单时指定。
4.4 系统部署图

APP端为同城快递app,基于react开发;
Nginx两台服务器+Keepalived,API网关有2台服务器,内部微服务也都有2台服务器,保证高可用;
Nacos 3台服务器,Elasticsearch 3台服务器,保证高可用的自动选举;
MySQL主从共4台,各2组主从,做好主主复制,主从复制;
Redis 3台,1主2从的哨兵模式,暂时不做redis cluster。
4.5 服务器时序图
1) 下单场景
为了响应的迅速,用户下单后,订单服务将其保存至数据库就返回下单成功(已下单状态);此后查找附近的快递员,通过消息队列发送消息给快递员的app,都是异步操作。

2) 抢单场景
考虑到并发量,正常DB 8核16G的低配置支撑一两千并发,16核32G的普遍配置支撑三四千的并发,所以更新数据库中订单已接单的操作不需要做异步处理;为了提高性能,判断订单是否已接单用redis来处理,而不访问数据库,redis setnx成功才更新数据库。

4.6 订单状态图

以上涉及两种订单状态,合法的订单终止状态为:物流的已取消和支付的已取消;物流的快递员已送达和支付的已支付。
5. 关键质量属性的设计原理
[内容:因软件系统的不同,性能、安全性、可伸缩性、互操作性、可扩展性、可测试性、可重用性、可维护性等质量属性,都可以是本系统的关键质量属性。
性能:
订单服务将查询请求和更新请求分为独立的包,未来可做命令和查询职责分离,独立部署,分别做读写
优化。其他优化点上文已涉及,包括缓存按城市做数据分片,数据库按城市做数据分片,消息队列的异步场景等。
可伸缩性:
微服务和其他各中间件组件均方便做水平扩展。
可测试性和可维护性:
使用容器化发布结合配置中心,方便版本的回滚和发布,方便敏捷开发流程。
安全性:
依赖APP端下单,可采用https通信协议。
评论