# device **Repository Path**: wxbLymm/device ## Basic Information - **Project Name**: device - **Description**: 测试 设备使用mqtt - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2025-09-24 - **Last Updated**: 2025-10-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: SpringBoot, mqtt, JWT, Security, Netty ## README # 设备管理系统 ## 项目概述 设备管理系统是一个基于Spring Boot开发的物联网设备管理平台,支持通过Netty和MQTT协议与设备进行通信,提供设备连接管理、数据采集、实时监控等功能。系统采用双数据库架构,MySQL存储设备基础信息,TDengine存储设备时序数据,确保高效的数据存储和查询。 ## 架构 - 现阶段还是经典三层架构 ## 现在已经加入新架构的基建类 ### 1. **使用的设计模式:** - **命令模式 (Command Pattern)**: `Action` 和 `ActionContext` 体现了命令模式的应用,每个业务操作被封装成一个独立的命令(`Action`),可以由 `ActionDispatcher` 调度执行。 - **模板方法模式 (Template Method Pattern)**: `BaseAction` 类使用了模板方法模式,定义了执行流程的骨架,子类(如 `GetUserDocAction`)只需要实现核心的 `process` 方法。 - **工厂模式 (Factory Pattern)**: `SpringContextHolder` 提供了工厂模式的功能,它负责从 Spring 容器中获取 `Action` 实例。 - **策略模式 (Strategy Pattern)**: 通过不同的 `ActionContext` 子类以及相应的 `Action` 实现,系统可以根据业务上下文来决定选择哪一个策略(即具体的 `Action` 子类)来执行。 - **责任链模式 (Chain of Responsibility)**: 虽然不是完全典型的责任链模式,但 `BaseAction` 中通过 `init`, `preprocess`, `validate`, `process`, `postprocess` 的方法划分了执行过程的多个步骤,类似于责任链模式中的任务分解。 ### 2. **各类的作用解析:** #### **Action Interface (`Action`)** - **作用**: 这是一个通用的接口,定义了执行方法 `execute`。每个 `Action` 都需要实现此接口,用来封装具体的业务逻辑。 - **设计模式**: 命令模式,通过 `execute` 方法来执行某个业务操作。 #### **ActionContext Interface** - **作用**: 这是一个上下文接口,封装了业务操作所需的参数和结果。提供了 `getResultMap`, `setResult`, `setDoc` 等方法,来处理操作的上下文数据。 - **设计模式**: 命令模式的上下文部分,保存命令执行前后的状态。 #### **BaseAction** - **作用**: 这是一个抽象类,继承了 `Action` 接口,使用模板方法模式定义了业务操作执行的流程框架(`init`, `preprocess`, `validate`, `process`, `postprocess`),其中 `process` 是需要子类实现的核心业务逻辑。 - **设计模式**: 模板方法模式,允许子类复用框架代码,并实现具体业务逻辑。 #### **BaseActionContext** - **作用**: 实现了 `ActionContext` 接口,提供了默认的上下文处理能力,保存了操作的文档(`doc`)和结果(`resultMap`),以及参数(`paramsMap`)。它是一个业务操作的上下文容器。 - **设计模式**: 命令模式的上下文部分,用于保存和传递业务操作相关的数据。 #### **BusinessException** - **作用**: 自定义的业务异常类,封装了业务错误码(`BusinessCode`)、业务类型、异常信息和 HTTP 状态码,用于处理业务操作中的异常情况。 - **设计模式**: 用于异常处理模式,增强了 Spring 的异常机制,提供业务层面的异常处理。 #### **ActionDispatcher** - **作用**: 核心的业务调度类,根据 `ActionContext` 自动匹配并执行相应的 `Action`。它的 `execute` 方法负责查找 `Action` 类,并通过 Spring 的 IOC 容器实例化相应的 `Action` 对象并执行。 - **设计模式**: 工厂模式,通过 Spring 容器来动态获取 `Action` 对象,并执行对应的命令。 #### **SpringContextHolder** - **作用**: 该类是一个 Spring 的工具类,用于获取 Spring 容器中的 Bean,方便在业务代码中注入和获取 Spring 管理的对象。 - **设计模式**: 工厂模式,它从 Spring IOC 容器中生成所需的 `Bean` 对象。 ### 环境要求 - JDK 17+ - Maven 3.6+ - MySQL 8.0+ - TDengine 3.0+ ### 安装步骤 1. 克隆代码仓库 2. 配置数据库连接(修改application.yml) 3. 运行 `./gradlew clean build` 构建项目 4. 执行 `java -jar build/libs/device-0.0.1-SNAPSHOT.jar` 启动应用 ### 环境准备 - JDK 17+ - MySQL 8.0+ - TDengine 3.0+ - MQTT Broker(如Mosquitto、EMQ X等) ### 部署步骤 1. 配置数据库连接(application.yml) 2. 配置MQTT Broker连接信息 3. 配置Netty服务端口和线程数 4. 打包项目:`./gradlew clean build` 5. 启动应用:`java -jar build/libs/device-0.0.1-SNAPSHOT.jar` ### Jenkins部署 提交代码即可自动更新部署云服务 ``` 地址:http://14.103.171.191:9090/job/device-java ``` ### 开发指南 #### 1. 构建工具 项目使用Gradle作为构建工具,主要构建命令: ```bash # 构建项目 ./gradlew build # 运行测试 ./gradlew test # 清理构建产物 ./gradlew clean # 打包JAR文件 ./gradlew jar ``` ## 项目架构 项目采用标准的MVC架构和模块化设计: ``` org.test.device/ ├── config/ # 配置类 │ ├── netty/ # Netty相关配置 │ └── mqtt/ # MQTT相关配置 ├── controller/ # Web控制器 ├── service/ # 业务逻辑层 ├── dao/ # 数据访问层 ├── entity/ # 实体类 ├── utils/ # 工具类 └── Application.java # 应用入口类 ``` ### 系统架构图 ``` +-------------------------------------------+ | 前端应用 | +-------------------------------------------+ | ↓ +-------------------------------------------+ | Spring Boot 应用 | | +---------------+ +--------------------+ | | | Web API模块 | | WebSocket实时推送 | | | +---------------+ +--------------------+ | | +---------------+ +--------------------+ | | | Netty服务 | | MQTT通信模块 | | | +---------------+ +--------------------+ | +------------------+------------------------+ | | ↓ ↓ +---------------+ +--------------------+ | 设备连接池 | | MQTT Broker | +---------------+ +--------------------+ | | ↓ ↓ +-------------------------------------------+ | 数据存储层 | | +---------------+ +--------------------+ | | | MySQL | | TDengine | | | | 设备基础信息 | | 时序数据存储 | | | +---------------+ +--------------------+ | +-------------------------------------------+ ``` ### 核心模块 - **设备通信模块**:基于Netty和MQTT的双通道通信 - **数据存储模块**:MySQL和TDengine双数据库架构 - **API服务模块**:RESTful接口,提供设备管理和数据查询 - **实时推送模块**:WebSocket实现数据实时推送 ## 项目技术栈 ### 核心技术 - **Spring Boot**:3.5.6 - 应用程序框架 - **Java**:17 - 开发语言 - **Netty**:4.2.0.Final - 高性能网络通信框架,用于设备通信 - **MySQL**:8.0.19 - 主数据库,存储设备基础信息 - **TDengine**:3.2.7 - 时序数据库,存储设备采集数据 - **MQTT**:6.5.0 (Spring Integration) + 1.2.5 (Paho) - 物联网消息协议,用于设备通信 - **MyBatis-Plus**:3.5.7 - ORM框架,简化数据库操作 - **WebSocket**:2.7.18 - 实时通信,用于前端推送 - **Druid**:1.2.16 - 数据库连接池 - **Dynamic Datasource**:3.6.1 - 动态数据源管理 - **Lombok**:1.18.30 - 代码简化工具 - **Fastjson2**:2.0.57 - JSON处理库 - **Redis**:缓存服务,用于Token存储和会话管理 - **线程池**:异步处理,提高系统性能 ### 设计模式 - **责任链模式**:基于BaseAction实现的业务流程处理框架,支持灵活的业务逻辑扩展 - **命令模式**:通过ActionDispatcher统一调度执行不同的业务命令 - **模板方法模式**:BaseAction定义标准执行流程(init→preprocess→validate→process→postprocess) - **观察者模式**:NettyCallbackCenter实现异步事件回调处理 - **单例模式**:ActionDispatcher等核心组件采用单例设计 - **工厂模式**:对象创建与管理的集中化处理 ## Netty通信模块详解 ### 1. 核心组件架构 Netty模块采用经典的C/S架构设计,主要包含以下核心组件: - **NettyServer**:服务端核心类,负责初始化和启动Netty服务器 - **NettyClient**:客户端测试类,用于快速测试连接和消息发送 - **NettyClientManager**:客户端管理器,提供更高级的连接管理和消息发送功能 - **NettyProperties**:配置属性类,统一管理Netty相关配置 - **NettyServerInitializer**:服务器初始化器,负责配置ChannelPipeline和处理器链,异步启动Netty服务 - **ServerHandler**:服务端业务处理器,处理接收到的消息 - **ClientHandler**:客户端业务处理器,处理服务器响应 - **HeartbeatHandler**:心跳处理器,实现连接保活机制 ### 2. 服务端实现 **NettyServer** 类实现了高性能的网络服务器: - 采用双线程组设计:Boss线程组负责接收新连接,Worker线程组负责处理I/O事件 - 使用LengthFieldBasedFrameDecoder解决TCP粘包/拆包问题 - 集成IdleStateHandler实现连接空闲检测和心跳机制 - 通过责任链模式组织ChannelHandler,实现请求的逐步处理 - 采用线程池异步处理业务逻辑,避免阻塞I/O线程 关键代码结构: ```java public void start() { // 1. 创建Boss和Worker线程组 // 2. 配置ServerBootstrap // 3. 设置TCP参数 // 4. 配置ChannelHandler链 // 5. 绑定端口并启动服务 } ``` #### 2.1 NettyServerInitializer详解 **NettyServerInitializer** 是Netty服务的关键组件,实现了CommandLineRunner接口,负责异步初始化和启动Netty服务: - **异步启动机制**:通过Spring的TaskExecutor在独立线程中启动Netty服务,避免阻塞Spring容器的启动过程 - **生命周期管理**:利用Spring Boot的CommandLineRunner接口,确保在应用启动后自动初始化Netty服务 - **解耦设计**:将Netty服务的启动逻辑从主应用流程中分离,提高代码可维护性 核心实现: ```java @Override public void run(String... args) throws Exception { // 使用线程池异步启动Netty,避免阻塞 primaryTaskExecutor.execute(() -> { log.info("[NettyServerInitializer]准备启动Netty服务器..."); nettyServer.start(); }); } ``` **注意**:实际的ChannelPipeline配置、编解码器设置和心跳检测是在NettyServer类的start()方法中通过匿名内部类实现的ChannelInitializer完成的。 ### 3. 客户端实现 项目提供两种客户端实现: #### 3.1 测试客户端(NettyClient) - 用于快速测试连接和消息发送 - 简单直接,适合开发测试 #### 3.2 高级客户端管理器(NettyClientManager) - 提供完整的连接生命周期管理 - 自动重连机制 - 线程安全的消息发送接口 - 集成Spring容器,可在其他组件中注入使用 关键特性: - 双重检查锁定确保线程安全 - 自动重连机制(可配置重连延迟) - 同步/异步消息发送 - 优雅关闭资源 ### 4. 消息编解码与处理 #### 4.1 编解码策略 - 使用LengthFieldBasedFrameDecoder和LengthFieldPrepender解决粘包/拆包 - StringDecoder/StringEncoder简化字符串消息处理 #### 4.2 消息处理器 - **ServerHandler**:处理业务逻辑,异步执行耗时操作 - **ClientHandler**:处理服务器响应和连接事件 - **HeartbeatHandler**:实现心跳检测机制 ### 5. 心跳与空闲检测 - 服务器端:30秒无读写则关闭连接,50秒无写操作则发送心跳 - 客户端:收到心跳请求自动回复PONG - 通过IdleStateHandler实现定时检测 ### 6. 线程模型 - **Boss线程组**:默认CPU核心数,负责接收新连接 - **Worker线程组**:默认CPU核心数×2,负责处理I/O事件 - **业务线程池**:由Spring管理,用于异步执行业务逻辑 ## 测试方法 ### 云测试方法 1. 云服务已部署 2. 下载代码后,不必启动DeviceApplication 3. 直接执行NettyClient的main方法 4. 查看控制台打印日志验证通信 ### 本地测试方法 1. 修改application.yml配置: ```yaml netty: serverHost: localhost # 设置为本地地址 port: 8888 # 保持端口一致 ``` 2. 启动DeviceApplication主程序 3. 执行NettyClient的main方法 4. 查看打印日志验证本地通信 ## 配置说明 ### Netty配置项 | 配置项 | 说明 | 默认值 | 建议值 | |-------|------|-------|-------| | serverHost | Netty服务绑定地址 | localhost | 根据部署环境调整 | | port | 服务监听端口 | 8888 | 避免冲突即可 | | bossThreadCount | Boss线程数 | CPU核心数 | 1-2倍CPU核心数 | | workerThreadCount | Worker线程数 | CPU核心数×2 | 2-4倍CPU核心数 | | connectTimeout | 连接超时时间 | 30000ms | 10000-60000ms | | reconnectDelay | 重连延迟时间 | 5s | 根据实际需求调整 | | maxFrameLength | 最大帧长度 | 65535字节 | 65535-1048576字节 | ## 最佳实践 1. **消息大小限制**:服务端限制单条消息最大10KB,避免内存溢出 2. **异步处理**:业务逻辑通过线程池异步执行,防止阻塞Netty I/O线程 3. **异常处理**:完善的异常捕获和日志记录机制 4. **资源管理**:使用@PreDestroy确保优雅关闭资源 5. **线程安全**:使用ReentrantLock确保并发环境下的线程安全 ## MQTT通信模块 ### 1. 模块概述 MQTT模块提供了基于发布/订阅模式的物联网通信能力,使用Spring Integration和Paho客户端实现。该模块支持设备通过MQTT协议进行数据上报和命令接收,适用于低带宽、不可靠网络环境下的设备通信。 ### 2. 核心组件 - **MqttConfig**:MQTT客户端配置类,管理连接参数和回调处理 - **MqttGateway**:消息发送网关,提供发布消息的接口 - **MqttMessageHandler**:消息处理器,处理接收到的MQTT消息 - **MqttProperties**:MQTT相关配置属性 ### 3. 主要特性 - **持久会话**:确保断开重连后不会丢失消息 - **QoS支持**:支持QoS 0/1/2级别,满足不同消息可靠性需求 - **断线重连**:自动检测连接状态,实现断线重连 - **消息重试**:失败消息的自动重试机制 - **遗嘱消息**:设备异常离线时自动发送离线通知 ### 4. 消息主题设计 ``` 设备上报数据:devices/{deviceId}/data 设备状态上报:devices/{deviceId}/status 设备命令下发:devices/{deviceId}/commands 系统广播消息:system/broadcast ``` ## API文档 本项目使用Knife4j作为API文档生成工具,基于OpenAPI/Swagger 3.0规范,提供了完整的在线接口文档与调试功能。 ### 访问方式 启动应用后,可以通过以下地址访问API文档: ``` http://14.103.171.191:8080/doc.html ``` ### 文档特性 - **自动生成**:基于代码注释自动生成API文档 - **在线调试**:支持直接在浏览器中测试API接口 ### JWT认证机制 本系统采用双Token(Access Token + Refresh Token)的认证机制,提高安全性和用户体验: #### Token说明 - **Access Token**:短期令牌,用于接口鉴权,默认有效期较短 - **Refresh Token**:长期令牌,用于刷新Access Token,有效期较长 #### 获取Token 通过登录接口获取初始的双Token: ```http POST /auth/login Content-Type: application/json { "username": "用户名", "password": "密码" } ``` 响应示例: ```json { "code": 200, "message": "登录成功", "data": { "accessToken": "eyJ...", "refreshToken": "eyJ..." } } ``` #### 使用Token 调用需认证的接口时,在请求头中携带Access Token: ``` Authorization: Bearer {accessToken} ``` #### 刷新Token 当Access Token过期时,使用Refresh Token获取新的Access Token: ```http POST /auth/refreshToken Content-Type: application/json { "refreshToken": "eyJ..." } ``` #### 退出登录 用户退出时,应调用退出接口清除令牌: ```http POST /auth/logout ``` #### 安全机制 - Refresh Token存储在Redis中,支持快速失效 - 每次请求验证Access Token的有效性 - 认证信息存储在ThreadLocal中,保证线程安全 - 测试环境可使用测试Token:`test_token_123` ### 接口分类 - 设备管理接口:设备注册、状态查询、参数配置等 - 数据采集接口:设备数据查询、统计分析等 - 消息推送接口:命令下发、状态通知等 - 系统管理接口:用户权限、系统配置等 ## 数据库设计 ### MySQL数据库 主要存储设备基础信息、用户信息、权限配置等结构化数据: - **device表**:设备基本信息(ID、名称、型号、状态等) - **device_group表**:设备分组信息 - **user表**:用户信息 - **permission表**:权限配置 ### TDengine数据库 专用于存储设备时序数据: - **device_data表**:设备采集的原始数据 - **device_metrics表**:设备指标计算结果 ## 常见问题排查 1. **连接失败**:检查IP地址、端口配置,确保防火墙开放 2. **消息发送失败**:检查消息格式,确认编解码器配置一致 3. **心跳超时**:检查网络稳定性,可适当调整心跳间隔 4. **性能问题**:调整线程池参数,增加Worker线程数 5. **MQTT连接问题**:检查Broker地址、客户端ID、认证信息 6. **数据库连接失败**:验证数据库配置和网络连通性