机器人租赁系统类擎天租平台技术栈的落地实录:Spring Cloud + Vue + MQTT

一、服务划分清单:一张表说清每个服务干什么

先上全景。后端基于 Spring Cloud Alibaba(Nacos + Sentinel + Seata 按需),服务划分和职责如下:

服务名 核心职责 对外协议 独立存储
gateway-service 统一入口、按端鉴权、限流 HTTP/WebSocket -
goods-service 机型库、设备档案、定价策略 HTTP MySQL goods 库
schedule-service 档期预占、冲突检测、日历 HTTP MySQL schedule 库 + Redis
order-service 订单状态机、签约编排、履约 HTTP MySQL order 库
payment-service 收付、押金冻结、分账、免押 HTTP MySQL pay 库
iot-service MQTT 接入、设备影子、围栏告警 MQTT + HTTP TDengine + Redis
ticket-service 维修工单、纠纷处理 HTTP MySQL ticket 库
notify-service 短信/订阅消息/邮件通知 HTTP(消费 MQ) MySQL
auth-service 统一认证、租户与权限 HTTP MySQL

三个划分原则:一是按业务能力不按技术分层 ;二是有独立伸缩诉求的先拆 (schedule 和 iot 是第一批);三是服务数量克制------九个服务是服务五家租赁商时的规模,起步阶段六个就够,notify 和 ticket 可以先做成单体里的模块。

Nacos 做注册中心和配置中心,配置按 服务名 + 租户标识 双维度隔离,租户级价格策略全部走配置下发,改策略不发版。Sentinel 的流控规则针对档期接口单独配了热点参数限流:以 deviceId 为参数维度,单设备 QPS 20,避免某台热门机型打爆整个服务。

二、前端方案:uni-app 一套代码跑三端

用户端(小程序 + APP + H5)用 uni-app + Vue3 + TypeScript。不是无脑信"一套代码多端运行",而是先盘了端差异:

  • 小程序是获客主入口,审核和包体有约束;
  • APP 主要是商家调度员用,需要蓝牙扫码、离线缓存;
  • H5 用于营销落地页和分享跳转。

三端页面重合度实测约 75%,剩下 25% 用条件编译消化:

js 复制代码
// #ifdef MP-WEIXIN
// 小程序专属:订阅消息授权
uni.requestSubscribeMessage({ tmplIds: [ORDER_TMPL] })
// #endif

// #ifdef APP-PLUS
// APP 专属:蓝牙扫描设备 SN 码绑定
const ble = uni.requireNativePlugin('bluetooth-scanner')
// #endif

两条实战纪律:页面层不写平台分支 ,差异全部下沉到 platform/ 适配层,页面只调用统一接口;公共组件库独立 npm 包管理,避免多项目复制粘贴导致样式漂移。商家端管理后台是纯 Vue3 + Element Plus 的 PC 端,表单密度高、报表多,和用户端彻底分开,不强行复用。

包体积控制上踩过一个坑:小程序主包超过 2MB 审核受影响。最后把 echarts、地图 SDK 全部拆分包异步加载,主包压回 1.6MB。

三、MQTT 选型 EMQX:规则引擎是真香,但要会配

设备接入为什么选 EMQX?三个理由:开源版功能足够(_acl、认证、桥接都有)、单节点十万级连接、最关键的是内置规则引擎能把大部分数据流转逻辑做成配置而不是代码

Topic 规划采用 业务域/租户/设备/动作 四段式:

复制代码
robot/{tenantId}/{deviceId}/telemetry   # 遥测上报(QoS0)
robot/{tenantId}/{deviceId}/status      # 上下线状态(QoS1)
robot/{tenantId}/{deviceId}/cmd/down    # 指令下发(QoS1)
robot/{tenantId}/{deviceId}/event       # 异常事件告警(QoS1)

规则引擎配置示例(SQL 形式),把遥测消息分流:

sql 复制代码
SELECT payload.temp, payload.battery, clientid, topic
FROM "robot/+/+/telemetry"
WHERE payload.battery < 20

命中规则后三个动作并行:遥测数据写入 TDengine(HTTP 服务)、低电量事件投递 Kafka 供告警服务消费、设备最新状态更新到 Redis。规则引擎做了 80% 的数据流转,Java 侧只剩业务语义处理,iot-service 的核心代码量比预想少了近一半。

三个必须注意的坑:

  1. 设备端断网重连风暴:一次机房网络抖动,2000 台设备同时重连,EMQX 连接数峰值打满。解法是设备端重连加随机退避(1-30s 抖动),EMQX 侧开启连接速率限制;
  2. QoS 别乱用:遥测用 QoS0 就够(丢了有下一条),指令下发必须 QoS1 + 业务层幂等(指令带 msgId 去重表)。全 QoS1 会让 broker 持久化压力翻倍;
  3. 共享订阅做横向扩展 :多个 iot-service 实例消费同一 Topic 要用 EMQX 的共享订阅($share/g/robot/+/+/event),否则每个实例都会收到全量消息,告警重复发。

四、部署拓扑与 CI/CD:从提交到上线一条流水线

生产环境 Kubernetes 部署,中间件(EMQX、RocketMQ、TDengine)独立部署不走 K8s------有状态服务的运维复杂度和无状态服务不是一回事,别硬塞进集群。

复制代码
开发者 push → GitLab MR + Code Review
→ 流水线:编译 → 单测(覆盖率门禁 60%)→ Sonar 扫描
→ 构建镜像 → 部署测试环境 → 自动化接口测试
→ 人工审批 → 滚动更新生产(金丝雀 10% → 全量)

前端 uni-app 在流水线里按端分别构建:小程序产物上传预览包给测试扫码,APP 走云打包出安装包,H5 直接发 CDN。MQTT 压测用 emqtt-bench 模拟 5 万设备连接 + 1000 msg/s 上报,作为大版本前的固定回归项。

流水线里最值钱的一条配置是档期并发回归测试:JMeter 脚本模拟 500 并发抢同一设备同档期,断言档期记录数必须等于 1,任何改动破坏了并发防护,流水线直接红。

五、总结与最佳实践

  • 服务划分先满足伸缩诉求(档期、IoT 先行),数量克制,九个服务是成长中的形态不是起点;
  • uni-app 三端落地,重合度 75% 是实测值不是宣传值,条件编译 + 适配层纪律决定可维护性;
  • EMQX 规则引擎把数据流转配置化,Java 侧只留业务语义;共享订阅、QoS 分级、重连退避是三个必做项;
  • CI/CD 的核心不是工具链,是"并发回归这类业务护栏"要进流水线;
  • 有状态中间件独立部署,K8s 只装无状态服务。
相关推荐
VV158897262013 天前
机器人租赁平台开发从0到1-整体架构设计与技术选型全解析
机器人租赁平台·机器人租赁系统·机器人租赁小程序·机器人租赁源码