砍材农夫砍材农夫
  • 微信记账小程序
  • java
  • redis
  • mysql
  • 场景类
  • 框架类
  • vuepress搭建
  • hexo搭建
  • 云图
  • llm wiki

    • 基于karpathy
    • gradle
  • 常用工具

    • git
    • gradle
    • Zadig
    • it-tools
    • 开源推荐
    • curl
  • 大前端

    • 环境配置
    • 微信生态
    • 正则
    • 全栈技能
  • java圈

    • java基础
    • jdk体系
    • jvm
    • spring框架
    • 分库分表
    • zookeeper
  • python技能

    • python编程
    • python数据
  • 算法

    • 算法
  • 网关

    • spring_cloud_gateway
    • openresty
  • 高可用

    • 秒杀
    • 分布式
    • 缓存一致
  • MQ

    • MQ
    • rabbitMQ
    • rocketMQ
    • kafka
  • 其它

    • 设计模式
    • 领域驱动(ddd)
  • 关系型数据库

    • mysql5.0
    • mysql8.0
  • 非关系型数据库

    • redis
    • mongoDB
  • 分布式/其他

    • ShardingSphere
    • 区块链
  • 向量数据库

    • M3E
    • OPEN AI
  • Jmeter
  • fiddler
  • wireshark
  • AI入门
  • AI大模型
  • AI插件
  • AI集成框架
  • 相关算法
  • AI训练师
  • 量化交易
  • AIoT
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 相关运营
  • devops
  • 元宇宙
  • 区块链
  • 物联网
  • webrtc
  • web3.0
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 中考
  • 投资
  • 保险
  • 思
  • 微信记账小程序
  • java
  • redis
  • mysql
  • 场景类
  • 框架类
  • vuepress搭建
  • hexo搭建
  • 云图
  • llm wiki

    • 基于karpathy
    • gradle
  • 常用工具

    • git
    • gradle
    • Zadig
    • it-tools
    • 开源推荐
    • curl
  • 大前端

    • 环境配置
    • 微信生态
    • 正则
    • 全栈技能
  • java圈

    • java基础
    • jdk体系
    • jvm
    • spring框架
    • 分库分表
    • zookeeper
  • python技能

    • python编程
    • python数据
  • 算法

    • 算法
  • 网关

    • spring_cloud_gateway
    • openresty
  • 高可用

    • 秒杀
    • 分布式
    • 缓存一致
  • MQ

    • MQ
    • rabbitMQ
    • rocketMQ
    • kafka
  • 其它

    • 设计模式
    • 领域驱动(ddd)
  • 关系型数据库

    • mysql5.0
    • mysql8.0
  • 非关系型数据库

    • redis
    • mongoDB
  • 分布式/其他

    • ShardingSphere
    • 区块链
  • 向量数据库

    • M3E
    • OPEN AI
  • Jmeter
  • fiddler
  • wireshark
  • AI入门
  • AI大模型
  • AI插件
  • AI集成框架
  • 相关算法
  • AI训练师
  • 量化交易
  • AIoT
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 相关运营
  • devops
  • 元宇宙
  • 区块链
  • 物联网
  • webrtc
  • web3.0
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 中考
  • 投资
  • 保险
  • 思
  • 首页
    • 开发板介绍
    • micropython环境搭建
    • esp32开发板
    • 面包板
    • 万能表使用
  • 面包板
    • 点灯
  • esp32
    • 点亮开发板led灯
    • 点亮外接led
    • 点亮外接oled文字
    • 红外传感器
    • 红外传感器+olde
    • esp32+面包板
  • MQTT编程

    • MQTT入门

      • 物联网 MQTT
      • 物联网 MQTT和Socket
      • 物联网 MQTT订阅性能优势
      • 物联网 MQTT简易版Broker
    • HiveMQ

      • hivemq实战入门
    • Protobuf

      • Protobuf入门
      • Protobuf入门+梳理
      • Protobuf实战第一篇
    • emqx

      • emqx入门
    • mica

      • mica入门
    • netty

      • 入门

        • 基于netty构建入门
        • 理解粘包/拆包
        • 编解码器机制与自定义协议
        • 心跳和ack机制
        • mqtt服务demo演示
        • mqtt服务协议支持
        • mqtt服务udp支持
      • 协议规范

        • mqtt协议规范(发布/订阅模式)
        • mqtt协议规范(轻量级二进制协议)
        • mqtt协议规范(三种 QoS 等级)
        • mqtt协议规范(主题通配符订阅)
        • mqtt协议规范(遗嘱与保留消息)
      • 报文结构

        • 控制报文结构(报文分类)
        • 控制报文结构(连接与握手)
        • 控制报文结构(发布与接收)
      • 核心实战

        • 核心实战(握手与认证)
        • 核心实战(心跳保活机制)
        • 核心实战(会话管理)
        • 核心实战(安全)
    • mqtt-模拟器|客户端

      • 集成Paho

        • 设备模拟器设计
        • 设备模拟器演示
        • Paho拆解入门
        • Paho拆解核心
        • Paho拆解高性能
        • 其他客户端框架比较
      • NetAssist

        • 设备模拟器设计
      • hiveMq

        • hiveMq客户端
    • netty-mqtt-boot

      • 模块化设计
      • 统一接入层
      • 消息路由与流转层
      • 核心服务层
      • 业务应用层
      • 整体项目管理
      • 测试脚手架
      • 兼容支持
    • mqtt-压测

      • mqtt-jmeter

        • 模块化设计
      • ‌emqtt-bench

        • 模块化设计
    • mqtt-规则引擎

      • MQTT规则引擎
      • sql

        • 基于sql规则
      • ice

        • 模块化设计
      • Aviator

        • 模块化设计
      • Drools

        • 模块化设计
    • mqtt-实战问题

      • MQTT分布式集群

        • 分布式集群

          • 分布式集群意义
          • 如何构建分布式集群
          • 分布式集群简易版
          • mqtt入口HAProxy模拟负载
        • ignite

          • ignite入门
          • 模块化设计
      • 实战汇总

        • 分布式集群意义
  • mqtt-netty源码拆解

    • mqtt-netty源码拆解

      • Pipeline双向链表
      • MqttEncoder.INSTANCE
      • 分布式集群简易版
      • mqtt入口HAProxy模拟负载
  • 物联网实战|Spring Boot+Netty搭建MQTT核心服务层
    • 源码(sample-00-iot-core)
    • 模块概述
    • 是物联网平台的核心业务服务层,承上启下连接消息接入层(access)与上层业务应用。模块职责涵盖设备管理、设备认证、设备影子、规则引擎、时序数据存储等核心能力核心定位:不直接处理网络协议,仅接收经过接入层解析后的业务消息,执行规则匹配、状态同步、数据持久化等业务逻辑
    • 目录结构
    • 核心模块详解
      • 认证模块 (auth)
        • JwtAuthenticator
        • Authenticator 接口
      • 设备管理模块 (device)
        • DeviceRegistry
        • DeviceInfo
      • 设备影子模块 (shadow)
        • DeviceShadowManager 接口
        • ShadowSyncService
      • 规则引擎模块 (rule)
        • RuleEngine 接口
        • DroolsRuleEngine
        • Rule 模型
        • ActionExecutor
      • 时序存储模块 (storage)
        • TimeSeriesWriter 接口
        • TimeSeriesDataDO
        • SqliteTimeSeriesWriter
      • 事件监听模块 (listener)
        • DeviceStatusEventListener
        • RuleEventListener
    • 配置说明
      • 核心配置 (application-core.yml)
      • 异步任务 TraceId 配置
    • 数据库设计
      • 建表脚本
    • 消息处理流程
    • 扩展指南
      • 添加新的认证方式
      • 添加新的规则动作
      • 切换存储后端
    • 总结

物联网实战|Spring Boot+Netty搭建MQTT核心服务层

源码(sample-00-iot-core)

https://gitee.com/kcnf-iot/mqtt-boot/tree/master/sample-00

模块概述

是物联网平台的核心业务服务层,承上启下连接消息接入层(access)与上层业务应用。模块职责涵盖设备管理、设备认证、设备影子、规则引擎、时序数据存储等核心能力 核心定位:不直接处理网络协议,仅接收经过接入层解析后的业务消息,执行规则匹配、状态同步、数据持久化等业务逻辑

目录结构

sample-00-iot-core/
├── src/main/java/com/jysemel/iot/core/
│   ├── auth/                              # 认证模块
│   │   ├── JwtAuthenticator.java           # JWT认证
│   │   ├── Authenticator.java              # 认证接口
│   │   └── PasswordAuthenticator.java      # 密码认证
│   │
│   ├── config/                            # 配置类
│   │   └── CoreTraceIdTaskExecutorAsyncConfig.java  # 异步任务TraceId传递
│   │
│   ├── device/                           # 设备管理
│   │   ├── DeviceRegistry.java             # 设备注册表
│   │   ├── DeviceService.java              # 设备服务接口
│   │   ├── DeviceInfo.java                 # 设备信息模型
│   │   └── impl/
│   │       └── SqliteDeviceService.java    # SQLite设备服务实现
│   │
│   ├── listener/                         # 事件监听
│   │   ├── DeviceStatusEventListener.java  # 设备状态变更监听
│   │   ├── RuleEventListener.java          # 规则事件监听
│   │   └── MessageEventListener.java       # 消息事件监听
│   │
│   ├── rule/                             # 规则引擎
│   │   ├── RuleEngine.java                 # 规则引擎接口
│   │   ├── RuleRepository.java             # 规则仓储
│   │   ├── DroolsRuleEngine.java           # Drools规则引擎实现
│   │   ├── ActionExecutor.java             # 动作执行器
│   │   ├── RuleConfig.java                 # 规则配置
│   │   └── model/
│   │       ├── Rule.java                   # 规则业务模型
│   │       └── RuleDO.java                 # 规则实体
│   │
│   ├── shadow/                           # 设备影子
│   │   ├── DeviceShadowManager.java       # 设备影子管理接口
│   │   ├── ShadowStore.java               # 影子存储接口
│   │   ├── ShadowSyncService.java         # 影子同步服务
│   │   └── impl/
│   │       └── SqliteShadowStore.java      # SQLite实现
│   │
│   └── storage/                          # 时序存储
│       ├── TimeSeriesWriter.java           # 时序写入接口
│       ├── TimeSeriesReader.java          # 时序读取接口
│       ├── TimeSeriesDataDO.java           # 时序数据实体
│       ├── TimeSeriesDataRepository.java   # JPA仓储
│       └── impl/
│           └── SqliteTimeSeriesWriter.java # SQLite写入实现
│
└── src/main/resources/
    └── db/
        ├── schema.sql                     # 建表脚本
        └── init-data.sql                   # 初始化数据

核心模块详解

认证模块 (auth)

JwtAuthenticator

基于 JWT 的设备身份认证,继承 Authenticator 接口。 核心方法:

方法说明
authenticate(productKey, deviceKey, password)验证设备身份,生成JWT
generateToken(deviceInfo)生成JWT令牌
validateToken(token)验证JWT有效性
extractDeviceInfo(token)从令牌中提取设备信息

JWT Claims 结构:

{
  "sub": "{productKey}/{deviceKey}",  // 设备唯一标识
  "productKey": "product-001",
  "deviceKey": "device-001",
  "iat": 1750051200,                  // 签发时间
  "exp": 1750137600,                  // 过期时间(1天后)
  "scope": ["publish", "subscribe"]   // 权限范围
}

Authenticator 接口

public interface Authenticator {
    /**
     * 认证设备
     * @return 认证成功返回设备信息,否则返回null
     */
    DeviceInfo authenticate(String productKey, String deviceKey, String password);
    
    /**
     * 验证Token
     */
    boolean validateToken(String token);
}

设备管理模块 (device)

DeviceRegistry

基于本地 ConcurrentHashMap 的设备注册中心,提供设备在线状态管理。 核心方法:

方法说明
registerOnline(productKey, deviceKey)标记设备上线
registerOffline(productKey, deviceKey)标记设备离线
isOnline(productKey, deviceKey)查询设备是否在线
getOnlineDevices()获取所有在线设备列表

数据结构:

// 设备在线状态缓存
ConcurrentHashMap<String, Boolean> deviceOnlineCache;  // key: "productKey:deviceKey"

// 在线时间记录
ConcurrentHashMap<String, Long> deviceOnlineTimeCache;  // key: "productKey:deviceKey"

特性:

  • 线程安全
  • O(1) 时间复杂度查询
  • 自动清理过期记录

DeviceInfo

设备信息模型,包含设备元数据。

字段类型说明
productKeyString产品标识
deviceKeyString设备标识
deviceSecretString设备密钥(加密存储)
deviceNameString设备名称
statusString状态:ONLINE/OFFLINE/DISABLED
createdTimeLocalDateTime创建时间

设备影子模块 (shadow)

设备影子用于解决设备与云端的状态同步问题,支持期望状态(Desired)与上报状态(Reported)的差异计算。

DeviceShadowManager 接口

public interface DeviceShadowManager {
    void initializeShadow(String productKey, String deviceKey);
    Map<String, Object> getShadow(String productKey, String deviceKey);
    void updateDesired(String productKey, String deviceKey, Map<String, Object> desired);
    void updateReported(String productKey, String deviceKey, Map<String, Object> reported);
    Map<String, Object> syncShadow(String productKey, String deviceKey);
    void deleteShadow(String productKey, String deviceKey);
}

ShadowSyncService

设备影子同步服务实现,核心功能是维护期望状态与上报状态的差异(Delta)。

影子数据结构:

{
  "productKey": "product-001",
  "deviceKey": "device-001",
  "version": 1,
  "timestamp": 1750051200000,
  "desired": {
    "temperature": 25,
    "mode": "auto"
  },
  "reported": {
    "temperature": 23,
    "mode": "manual"
  },
  "delta": {
    "temperature": 25,
    "mode": "auto"
  }
}

Delta 计算逻辑:

Delta = Desired - Reported

只有期望值与上报值不同时,才会被加入 Delta。这意味着设备需要同步更新这些属性。


规则引擎模块 (rule)

规则引擎是核心业务能力,支持对设备消息进行条件匹配和动作执行。

RuleEngine 接口

public interface RuleEngine {
    /**
     * 初始化规则引擎
     */
    void initialize();
    
    /**
     * 评估规则
     * @param topic 消息主题
     * @param payload 消息内容
     * @return 匹配结果
     */
    EvaluationResult evaluate(String topic, byte[] payload);
    
    /**
     * 添加规则
     */
    void addRule(Rule rule);
    
    /**
     * 移除规则
     */
    void removeRule(String ruleId);
}

DroolsRuleEngine

基于 Drools 规则引擎的实现。

Drools 特性:

  • Rete 算法实现高效的规则匹配
  • 支持复杂的条件表达式
  • 规则热加载(动态更新规则库)
  • 透传 TraceId 到规则执行上下文

初始化流程:

DroolsRuleEngine.initialize()
    │
    ├── RuleRepository.loadAllRules()  加载规则
    │
    ├── buildKieModule()              构建Drools模块
    │
    └── startChangeScanner()         启动规则变更扫描(可选)

Rule 模型

@Data
public class Rule {
    private String ruleId;           // 规则ID
    private String ruleName;         // 规则名称
    private String ruleType;         // 规则类型
    private String status;           // 状态:ENABLED/DISABLED
    private Condition condition;     // 触发条件
    private List<Action> actions;    // 执行动作列表
    
    @Data
    public static class Condition {
        private String topic;              // 监听主题
        private String expression;         // 条件表达式
        private Map<String, String> params; // 参数
    }
    
    @Data
    public static class Action {
        private String actionType;   // 动作类型:PUBLISH/SAVE_DB/SMS/EMAIL
        private String target;       // 目标(主题/服务地址等)
        private Map<String, Object> params; // 动作参数
    }
}

规则示例:

{
  "ruleId": "rule-001",
  "ruleName": "温度告警规则",
  "ruleType": "TEMPERATURE_ALARM",
  "status": "ENABLED",
  "condition": {
    "topic": "device/{deviceKey}/telemetry",
    "expression": "temperature > 50"
  },
  "actions": [
    {
      "actionType": "PUBLISH",
      "target": "cloud/alarm",
      "params": {"level": "HIGH"}
    },
    {
      "actionType": "SAVE_DB",
      "params": {}
    }
  ]
}

ActionExecutor

动作执行器,负责执行匹配成功的规则对应的动作。

支持的動作類型:

动作类型说明用途
PUBLISH发布消息触发后续流程
SAVE_DB存储数据库数据持久化
SMS短信通知告警通知
EMAIL邮件通知告警通知
HTTPHTTP调用外部系统集成

时序存储模块 (storage)

TimeSeriesWriter 接口

public interface TimeSeriesWriter {
    /**
     * 写入时序数据
     * @param metric 度量名称
     * @param tags 标签(维度)
     * @param fields 字段(指标值)
     * @param timestamp 时间戳
     */
    void write(String metric, Map<String, String> tags, Map<String, Object> fields, long timestamp);
}

TimeSeriesDataDO

时序数据实体,SQLite 持久化。

字段类型说明
idLong主键
metricString度量名称(temperature/humidity)
tagsString标签,格式:k1=v1,k2=v2
fieldsString字段,格式:k1=v1,k2=v2
timestampLong时间戳(毫秒)

SqliteTimeSeriesWriter

SQLite 实现,通过 @ConditionalOnProperty 实现存储模式切换。


事件监听模块 (listener)

DeviceStatusEventListener

监听设备状态变更事件,触发设备影子初始化。

@Component
public class DeviceStatusEventListener {
    @EventListener
    public void onDeviceOnline(DeviceOnlineEvent event) {
        // 设备上线时初始化影子
        shadowService.initializeShadow(event.getProductKey(), event.getDeviceKey());
    }
}

RuleEventListener

监听消息事件,触发规则引擎评估。

@Component
public class RuleEventListener {
    @EventListener
    public void onMessage(MessageEvent event) {
        // 触发规则评估
        ruleEngine.evaluate(event.getTopic(), event.getPayload());
    }
}

配置说明

核心配置 (application-core.yml)

core:
  rule:
    enabled: true                      # 启用规则引擎
    engine: drools                      # 规则引擎类型
    scan-packages: com.jysemel.iot.core.rule.drools  # Drools规则包
    
  device:
    cache:
      enabled: true                    # 启用设备缓存
      ttl: 3600                       # 缓存TTL(秒)
      
  shadow:
    sync:
      enabled: true                   # 启用影子同步
      
  storage:
    mode: sqlite                      # 存储模式:sqlite/mysql

异步任务 TraceId 配置

配置异步任务的 TraceId 透传,确保异步日志链路完整。

@Configuration
public class AsyncConfig implements AsyncConfigurer {
    @Override
    public Executor getAsyncExecutor() {
        TaskExecutor executor = new TaskExecutor();
        executor.setTaskDecorator(new TraceIdTaskDecorator());
        return executor;
    }
}

数据库设计

建表脚本

-- 设备表
CREATE TABLE IF NOT EXISTS devices (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    product_key VARCHAR(100) NOT NULL,
    device_key VARCHAR(100) NOT NULL,
    device_name VARCHAR(200),
    device_secret VARCHAR(500),
    status VARCHAR(20) DEFAULT 'OFFLINE',
    created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(product_key, device_key)
);

-- 规则表
CREATE TABLE IF NOT EXISTS rules (
    rule_id VARCHAR(100) PRIMARY KEY,
    rule_name VARCHAR(200) NOT NULL,
    rule_type VARCHAR(50),
    status VARCHAR(20) DEFAULT 'ENABLED',
    condition_expression TEXT,
    condition_topic VARCHAR(500),
    condition_params TEXT,
    actions TEXT,
    create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 设备影子表
CREATE TABLE IF NOT EXISTS device_shadows (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    product_key VARCHAR(100) NOT NULL,
    device_key VARCHAR(100) NOT NULL,
    shadow_data TEXT,
    version INTEGER DEFAULT 1,
    created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(product_key, device_key)
);

-- 时序数据表
CREATE TABLE IF NOT EXISTS time_series_data (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    metric VARCHAR(100) NOT NULL,
    tags VARCHAR(500),
    fields TEXT,
    timestamp BIGINT NOT NULL,
    INDEX idx_metric_timestamp (metric, timestamp)
);

消息处理流程

消息接入层 (access)
    │
    ▼ 发布 MessageEvent
    │
核心服务层 (core)
    │
    ├── DeviceStatusEventListener
    │       └── 更新设备状态 → DeviceRegistry
    │
    ├── RuleEventListener
    │       └── 触发规则评估 → RuleEngine.evaluate()
    │               │
    │               ▼
    │           DroolsRuleEngine(规则匹配)
    │               │
    │               ▼
    │           ActionExecutor(执行动作)
    │               │
    │               ├── StorageWriter(存储数据)
    │               ├── DeviceShadowManager(更新影子)
    │               └── 其他Action
    │
    └── ShadowSyncService
            └── 同步影子状态

扩展指南

添加新的认证方式

实现 Authenticator 接口即可:

@Component
public class LdapAuthenticator implements Authenticator {
    @Override
    public DeviceInfo authenticate(String productKey, String deviceKey, String password) {
        // LDAP 认证逻辑
    }
    
    @Override
    public boolean validateToken(String token) {
        // Token 验证逻辑
    }
}

添加新的规则动作

在 ActionExecutor 中添加新的动作处理分支:

@ActionHandler("CUSTOM_ACTION")
public void handleCustomAction(Action action, EvaluationResult result) {
    // 自定义动作处理逻辑
}

切换存储后端

通过 @ConditionalOnProperty 添加新的存储实现:

@Component
@ConditionalOnProperty(name = "storage.mode", havingValue = "mysql")
public class MySqlTimeSeriesWriter implements TimeSeriesWriter {
    // MySQL 实现
}

总结

sample-00-iot-core 模块作为物联网平台的核心服务层,具备以下核心能力:

能力说明
设备管理设备注册、状态管理、在线追踪
身份认证JWT/密码双认证机制
设备影子Desired/Reported 状态同步,Delta 计算
规则引擎Drools 实现,支持复杂条件匹配和动作执行
时序存储支持多存储后端(SQLite/MySQL)
事件驱动Spring Event 机制实现模块解耦
链路追踪TraceId 透传到异步任务

模块设计遵循以下原则:

  • 可扩展:通过接口和策略模式支持多实现
  • 可配置:通过 @ConditionalOnProperty 实现功能开关
  • 可追踪:完整的日志和 TraceId 链路
  • 事件化:通过 Spring Event 实现松耦合
最近更新: 2026/6/22 08:54
Contributors: kcnf
Prev
消息路由与流转层
Next
业务应用层