版本
历史版本 | 日期 | 作者 |
---|---|---|
v 1.0.0.0 | 2018-04-04 | 大树 |
v 1.0.0.1 | 2018-04-04 | 大树 |
总体设计
图片 1.png核心业务架构
图片 2.pngIP:路由
客户端在使用长连接前,会调用路由服务,获取连接层IP,路由层特性:a. 可以按照百分比灰度;b. 未来可以对 uid,deviceId,版本进行区域区分设置。
MVP版本可以用Nginx、阿里云负载均衡方案解决。
接入层
接入层是接受端上发起的长连接服务。技术方案初步确认为:RabbitMq 做推送,MongoDB最为二维坐标存储,MQTT作为连接协议。
MQTT:
协议选择:
业务场景数据量影响。
实际网络通信频度及其性能影响。
对硬件影响。
安全性。
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的“轻量级”通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。MQTT最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。做为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。
特点包括:
- 使用的发布/订阅消息模式,它提供了一对多消息分发,以实现与应用程序的解耦。
- 对负载内容屏蔽的消息传输机制。
- 对传输消息有三种服务质量(QoS):
最多一次,这一级别会发生消息丢失或重复,消息发布依赖于底层TCP/IP网络。即:<=1
至多一次,这一级别会确保消息到达,但消息可能会重复。即:>=1
只有一次,确保消息只有一次到达。即:=1。在一些要求比较严格的计费系统中,可以使用此级别 - 数据传输和协议交换的最小化(协议头部只有2字节),以减少网络流量
- 通知机制,异常中断时通知传输双方
我们这里在实际应用场景司机需要不断的上传位置数据,所以为了通道性能,可选择Qos=0
RabbitMQ:
RabbitMQ在架构层次上充当接入层与推送层。
项目选择接入层必须满足以下几点要求:
1:单机长连接性能要求高。
2:可灵活扩容的集群分布式模式。
3:链接必须有足够的稳定性。
4: 具备一定的优先策略,让Priority高的接收者先接到数据
RabbitMQ是综上最优选择,Emq开源但是社区不够庞大,而且不支持作为非MQTT得消息队列进行使用。
Kafka具备高吞吐量高性能的特点,但是它是解决实时消息处理的队列而不适用于M2M的IOT场景。他主要是 broker-Customer模式。
存储层
MongoDB作为实时消息存储层,相对redis更适合我们业务场景,Redis虽然能满足mvp设计需要,但是它只能解决一部分业务,必须搭配其他方案进行存储。RDBMS的性能无法满足高频插入并进行工作队列编排任务。
业内MongoDB已经是处理此类业务的一个标配。
优点:
支持二维地理索引数据存储和查询(GeoJSON)
分布式部署
司机端基础服务
请求链接
名称 | 类型 | 备注 |
---|---|---|
driverId | Int | 司机ID |
名称 | 类型 | 备注 |
---|---|---|
clientId | string | Mqtt 客户端ID |
userName | string | 用户名 |
password | string | 密码 |
serverUri | string | 链接地址 |
publishedTopic | String | 发布位置的Topic |
subscribeOrderTopic | string | 订单通道 |
subscribeCalculateTopic | string | 算力订阅通道 |
subscribeGeneralTopic | string | 与区域相关的通用通知通道 |
发布位置
名称 | 类型 | 备注 |
---|---|---|
driverId | Int | 司机ID |
longitude | string | 经度(换算成double) |
latitude | string | 纬度(换算成double) |
processState | int | 行程状态,0是位置,1是行程开始(暂定) |
<em>orderId</em> | int | 订单ID<行程中,需要传,其他不需要传> |
订阅订单
名称 | 类型 | 备注 |
---|---|---|
orderId | Int | 订单Id |
orderNum | string | 订单编号 |
passengerId | string | 乘客ID |
passengerName | string | 乘客名 |
see | String | 预估算力 |
passengerPrice | int | 分(需要端上转换)预估价钱 |
订阅预约订单(不放第一迭代)
抢单
/trago/order/initiative
名称 | 类型 | 备注 |
---|---|---|
orderId | Int | 订单Id |
passengerId | string | 乘客ID |
driverId | Int | 司机ID |
- 发起抢单
- server接到请求,更改订单状态
- 如果订单状态已经是抢单中则不修改
- 投递到抢单队列
- 抢单对列进行判断,一单此单Mailbox已经满了,就直接返回抢单失败
- 没满,投递到队列,并排序。
- 队列满了之后,选出最优司机
- 发送【Topic】告知队列中所有司机抢单结果。
- 发送【Topic】告知乘客抢单结果
备注:第一期迭代建议不做复杂逻辑直接抢单成功。
抢单结果推送
名称 | 类型 | 备注 |
---|---|---|
orderId | Int | 订单Id |
success | int | 0失败 1成功 |
整体流程
DeriverUML Sequence Diagram.png乘客端基础服务
立即下单
请求
名称 | 类型 | 备注 |
---|---|---|
passengerId | string | 乘客ID |
passengerName | string | 乘客名 |
passengerSee | String | 预估算力 |
passengerPrice | int | 分(需要端上转换) |
返回
名称 | 类型 | 备注 |
---|---|---|
orderId | int | 订单Id |
轮训订单
/trago/passenger/query_order
请求
名称 | 类型 | 备注 |
---|---|---|
orderId | int | 订单Id |
passengerId | int | 乘客ID |
longitude | string | 经度(换算成double) |
latitude | string | 纬度(换算成double) |
processState | int | 行程状态,0是位置,1是行程开始(暂定) |
返回
名称 | 类型 | 备注 |
---|---|---|
orderId | int | 订单Id |
orderState | int | [具体根据产品的文档定状态,测试阶段,只涉及0,1] |
<em>driverId</em> | string | 经度(换算成double) |
乘客流程
PassengerUML Sequence Diagram.png内部BROKER设计
Toplic规范
- 反斜线分隔
- 第一位:drivers 、 passengers 、orders 代表角色
- 第二位:区域 1代表香港
- 第三位:事件 1代表位置 2代表订单消息,3代表算力消息,4代表通用消息
- 第四位:业务标记(driverid,passengerid,orderid)
Messag规范
第一期都用 application/json 内容协议
Broker规范
- 每一个Broker 有一个单独的ID
- Broker需要把本Broker订阅的所有Topic持久化
- Broker要避免不同Broker同时订阅同一个Topic
司机LBS实体
名称 | 类型 | 备注 |
---|---|---|
clientId | string | Mqtt 客户端ID |
driverId | Int | 司机ID |
longitude | string | 经度(换算成double)最新 |
latitude | string | 纬度(换算成double)最新 |
publishedTopic | String | 发布位置的Topic |
subscribeOrderTopic | string | 订阅订单Topic |
subscribeCalculateTopic | string | 算力订阅通道 |
其他LBS信息 | string | 后补充 |
乘客LBS实体
名称 | 类型 | 备注 |
---|---|---|
passengerId | int | 乘客Id |
orderId | Int | 司机ID |
longitude | string | 经度(换算成double)最新 |
latitude | string | 纬度(换算成double)最新 |
orderState | int | 状态 |
publisedOrderTopic | string | 订阅订单Topic |
其他LBS信息 | string | 后补充 |
行程中轨迹
名称 | 类型 | 备注 |
---|---|---|
orderId | int | 订单Id |
passengerId | int | 乘客ID |
driverId | int | 司机ID |
location | ||
<em>type </em> | string | line 保持与mongo格式一致 |
<em>latitude </em> | string | 纬度(换算成double) |
<em>latitude </em> | string | 纬度(换算成double) |
立即下单发布
请求
名称 | 类型 | 备注 |
---|---|---|
passengerId | int | 乘客Id |
orderId | Int | 订单ID |
longitude | string | 经度(换算成double)最新 |
latitude | string | 纬度(换算成double)最新 |
orderState | int | 状态 |
publisedOrderTopic | string | 订阅订单Topic |
其他LBS信息 | string | 后补充 |
订单状态同步发布
请求
名称 | 类型 | 备注 |
---|---|---|
passengerId | int | 乘客Id |
driverId | Int | 司机ID |
orderId | Int | 订单ID |
orderState | int | 状态 |
publisedOrderTopic | string | 订阅订单Topic |
网友评论