1. 为什么选择若依框架开发物联网平台
若依(RuoYi)作为国内流行的开源后台管理系统框架,在快速开发企业级应用方面具有显著优势。这个基于SpringBoot的权限管理系统采用主流技术栈(MyBatis、Shiro、Vue等),其模块化设计和丰富的功能组件特别适合作为物联网平台的基础架构。
我选择若依框架开发物联网平台主要基于以下考量:
- 权限控制完善:物联网平台涉及设备管理、数据权限等复杂场景,若依内置的RBAC权限模型和部门数据隔离机制可直接复用
- 代码生成器高效:平台需要大量设备管理CRUD界面,若依的代码生成器可快速产出标准化的前后端代码
- 多终端适配:支持PC、平板和移动端的响应式布局,符合物联网平台多端访问需求
- 社区生态丰富:活跃的开发者社区和大量现成插件,能显著降低物联网特定功能的开发成本
2. 物联网平台核心架构设计
2.1 技术栈选型
在若依标准技术栈基础上,物联网平台需要补充以下组件:
若依基础架构: - 后端:Spring Boot 2.7 + MyBatis Plus - 前端:Vue 3 + Element Plus - 安全:Shiro + JWT 物联网扩展组件: - 协议支持:Netty(TCP/UDP) + Paho MQTT Client - 设备管理:EMQX Broker 5.0(百万级设备连接) - 时序数据:InfluxDB 2.6(高性能时间序列存储) - 规则引擎:Node-RED(可视化业务流编排) - 监控告警:Prometheus + Grafana2.2 关键模块划分
graph TD A[设备接入层] --> B[协议适配模块] B --> C[设备管理服务] C --> D[数据持久化] D --> E[业务规则引擎] E --> F[可视化平台]3. 设备接入层实现细节
3.1 多协议适配方案
在ruoyi-system模块中新建iot-protocol子模块,采用策略模式实现协议适配:
// 协议接口定义 public interface ProtocolHandler { void process(byte[] payload, Channel channel); DeviceInfo parseDeviceInfo(); } // MQTT处理器实现 @Service("mqttHandler") public class MqttHandler implements ProtocolHandler { @Override public void process(byte[] payload, Channel channel) { // 解析MQTT特定报文格式 MqttMessage message = new MqttMessage(payload); String topic = message.getTopic(); // ...业务处理 } } // TCP处理器实现 @Service("tcpHandler") public class TcpHandler implements ProtocolHandler { // ...类似实现 }3.2 设备鉴权流程
改造若依原有的Shiro认证流程,增加设备级认证:
- 设备注册:通过若依的
sys_device表存储设备三元组(productKey, deviceName, deviceSecret) - 连接认证:设备上线时通过MQTT的username/password或TCP的加密报文进行身份验证
- 动态权限:根据设备类型绑定对应的数据发布/订阅权限
4. 数据持久化方案
4.1 时序数据存储
针对物联网高频数据特点,采用分层存储策略:
| 数据类型 | 存储方案 | 保留策略 | 查询特点 |
|---|---|---|---|
| 实时数据 | InfluxDB | 7天 | 毫秒级响应 |
| 历史数据 | TDengine | 1年 | 按需聚合 |
| 冷数据 | MinIO | 永久 | 离线分析 |
4.2 业务数据整合
在若依原有sys_表前缀基础上,新增物联网专用表:
CREATE TABLE iot_device ( device_id BIGINT PRIMARY KEY, product_key VARCHAR(64) NOT NULL, device_name VARCHAR(128) NOT NULL, status TINYINT DEFAULT 0, last_online_time DATETIME, meta_data JSON COMMENT '设备扩展属性' ) ENGINE=InnoDB; CREATE TABLE iot_property_log ( id BIGINT AUTO_INCREMENT, device_id BIGINT NOT NULL, identifier VARCHAR(64) NOT NULL, value DOUBLE PRECISION, report_time DATETIME(3) NOT NULL, PRIMARY KEY (id, report_time) ) ENGINE=InnoDB PARTITION BY RANGE (TO_DAYS(report_time)) ( PARTITION p202301 VALUES LESS THAN (TO_DAYS('2023-02-01')), PARTITION p202302 VALUES LESS THAN (TO_DAYS('2023-03-01')) );5. 平台功能扩展实践
5.1 规则引擎集成
在若依管理后台增加规则编排界面:
- 引入Node-RED编辑器前端组件
- 开发若依权限对接模块
- 实现流程版本管理和发布控制
关键配置示例:
# application-iot.yml nodered: editor: path: /iot/rule/designer auth: enabled: true admin-role: iot_admin storage: type: mysql table-prefix: iot_flow_5.2 可视化大屏
基于若依原有Echarts集成,开发设备监控专用组件:
<template> <div class="iot-dashboard"> <el-row> <el-col :span="12"> <device-status-chart :product-key="currentProduct"/> </el-col> <el-col :span="12"> <data-stream-chart :device-id="selectedDevice"/> </el-col> </el-row> </div> </template> <script> import { getDeviceRealTimeData } from '@/api/iot/device' export default { data() { return { currentProduct: null, selectedDevice: null } }, mounted() { this.initWebSocket() }, methods: { initWebSocket() { const ws = new WebSocket(`wss://${location.host}/iot/ws/device`) ws.onmessage = (event) => { const data = JSON.parse(event.data) this.$refs.statusChart.update(data) } } } } </script>6. 性能优化关键点
6.1 连接管理优化
针对海量设备连接场景,需要调整若依默认配置:
# EMQX配置 listeners.tcp.default = 0.0.0.0:1883 listeners.tcp.default.max_connections = 1000000 listeners.ssl.default = 0.0.0.0:8883 listeners.ssl.default.max_connections = 500000 # Spring Boot调优 server.tomcat.max-threads=2000 server.tomcat.accept-count=1000 spring.redis.lettuce.pool.max-active=20006.2 缓存策略设计
采用多级缓存减轻数据库压力:
- 本地缓存:Caffeine缓存设备基础信息
- 分布式缓存:Redis缓存实时状态数据
- 时序数据库缓存:InfluxDB下行采样策略
缓存更新策略示例:
@CacheEvict(value = "deviceMeta", key = "#deviceId") public void updateDeviceMeta(Long deviceId, DeviceMeta meta) { // 先更新数据库 deviceMapper.updateMeta(deviceId, meta); // 再清除相关缓存 redisTemplate.delete("device:stats:" + deviceId); }7. 安全防护方案
7.1 通信安全加固
- 传输加密:所有设备连接强制TLS 1.3
- 报文签名:采用SM4国密算法对关键指令签名
- 频控策略:基于若依的限流模块扩展设备级QPS控制
7.2 权限深度控制
扩展若依的@RequiresPermissions注解:
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface RequiresDevicePermission { String[] value(); Logical logical() default Logical.AND; } // 使用示例 @RequiresDevicePermission({"device:control", "device:config"}) @PostMapping("/control") public R controlDevice(@RequestBody DeviceCmd cmd) { // 业务逻辑 }8. 部署架构建议
8.1 生产环境拓扑
+-----------------+ | CDN/OSS | +--------+--------+ | +---------------+ +-------+-------+ +-----------------+ | Web前端集群 +---+ Nginx网关层 +---+ 若依应用集群 | +-------+-------+ +-------+-------+ +--------+--------+ | | | +-------+-------+ +-------+-------+ +--------+--------+ | 设备接入层 | | 消息中间件 | | 数据服务层 | | (EMQX集群) | | (Kafka) | | (MySQL+InfluxDB)| +---------------+ +---------------+ +-----------------+8.2 容器化配置示例
# EMQX容器配置 FROM emqx/emqx:5.0.26 COPY ./etc/plugins/emqx_auth_mysql.conf /opt/emqx/etc/plugins/ RUN echo "emqx_auth_mysql.enable = true" >> /opt/emqx/etc/emqx.conf # 若依应用容器 FROM openjdk:17-jdk COPY target/ruoyi-iot.jar /app/ ENTRYPOINT ["java","-jar","/app/ruoyi-iot.jar"]在物联网项目实施过程中,我发现若依的模块化设计能很好地适应物联网平台的扩展需求。特别是在权限管理和多租户支持方面,原有的系统架构几乎不需要修改就能直接应用。最大的挑战在于设备连接管理部分,需要合理设计会话保持机制,这部分建议结合EMQX的企业版功能进行深度定制