这一章给出一份可以直接写进项目立项书的技术栈,而不是罗列所有流行技术。每个选择都说明理由、版本和替代方案;你可以按团队情况替换,但要知道替换的代价。
1. 选型原则
| 原则 | 含义 | 反面案例 |
|---|---|---|
| 团队会什么就用什么 | 交付周期比技术先进性重要 | 团队没人写过 Go,却为了“高并发”上 Go |
| 能单体不微服务 | 能碳系统初期并发不高,复杂度在采集和业务 | 20 个点位就上 Nacos + Gateway + 链路追踪 |
| 时序数据用时序库 | 高频写入、按时间范围聚合是刚需 | 所有数据塞 MySQL,三个月后查询超时 |
| 协议适配要可插拔 | 现场协议五花八门,不能写死在业务里 | 每接一种表就改一次采集主流程 |
| 碳核算要可追溯 | 因子、口径、版本都会变 | 把排放因子写死在 Java 常量里 |
| 先跑通一条链路 | 电→网关→MQTT→库→页面→报表 | 同时接五种介质,哪种都不稳定 |
2. 技术栈总览
| 层次 | 技术 | 推荐版本 | 作用 | 选它的理由 |
|---|---|---|---|---|
| 语言 | Java | 8 或 17 | 后端主语言 | 若依生态成熟,工业协议库多 |
| 框架 | Spring Boot | 2.5.15 / 2.7.18 / 3.2.x | 应用底座 | 若依默认集成,资料多 |
| 底座 | RuoYi-Vue | 3.8.x | 权限、菜单、代码生成 | 开箱即用,二次开发成本低 |
| 安全 | Spring Security + JWT | 随若依 | 登录、鉴权、会话 | 若依已封装,改造成本低 |
| ORM | MyBatis | 随若依 | SQL 映射 | 复杂统计 SQL 可控 |
| 业务库 | MySQL | 8.0.36+ | 台账、配置、结果 | 通用、运维简单、云厂商支持好 |
| 缓存 | Redis | 7.2+ | Token、字典、最新值、锁 | 若依默认使用,生态成熟 |
| 时序库 | TDengine | 3.3.x | 原始数据、聚合数据 | 写入快、压缩高、SQL 友好、中文资料多 |
| 消息 | EMQX | 5.8.x | MQTT Broker | 工业物联网事实标准,集群和 ACL 完善 |
| 协议 | Modbus / DL/T 645 / OPC UA / IEC 104 | — | 现场设备接入 | 覆盖 90% 以上的电表和 PLC |
| 前端 | Vue 3 | 3.4+ | 页面框架 | 若依 Vue3 版官方支持 |
| UI | Element Plus | 2.x | 组件库 | 与若依风格一致,表单表格强 |
| 构建 | Vite | 5.x+ | 前端构建 | 启动快,配置简单 |
| 状态 | Pinia | 2.x | 全局状态 | Vue 3 官方推荐 |
| 图表 | ECharts | 5.5+ | 趋势、占比、能流 | 图表类型全,工业场景够用 |
| 导出 | EasyExcel | 3.3+ | Excel 导入导出 | 内存占用低,API 简单 |
| 定时任务 | Quartz(若依自带) | 随若依 | 聚合、报表、核算 | 不额外引入调度中心 |
| 实时推送 | WebSocket / SSE | — | 驾驶舱刷新、报警 | 比轮询省资源 |
| 对象存储 | MinIO | 最新稳定版 | 报告、附件、图片 | S3 兼容,可私有化 |
| 容器 | Docker + Compose | 26+ | 部署 | 环境一致,交付简单 |
| 反向代理 | Nginx | 1.26+ | 静态资源、HTTPS、转发 | 成熟稳定 |
| 监控 | Prometheus + Grafana | 最新稳定版 | 指标、告警、看板 | 云原生标准 |
| 日志 | Loki 或 ELK | 最新稳定版 | 日志检索 | 按团队熟悉度选 |
3. 后端:若依怎么选
3.1 三个版本的区别
| 版本 | 架构 | 技术特点 | 适合场景 | 注意 |
|---|---|---|---|---|
| RuoYi-Vue | 前后端分离单体 | Spring Boot 2.5.15、MyBatis、Spring Security、JWT | 中小型项目、单团队、快速交付 | 官方默认 JDK 8,Spring Boot 版本较老 |
| RuoYi-Cloud | Spring Cloud Alibaba 微服务 | Nacos、Gateway、Sentinel、OpenFeign | 多园区、多团队、需要独立扩容 | 运维复杂度高,需要 DevOps 能力 |
| RuoYi-Vue-Plus | 第三方增强单体 | Spring Boot 3、JDK 17、Sa-Token、MyBatis-Plus、Redisson | 想用新 JDK、需要多租户/工作流 | 第三方项目,需评估社区活跃度和升级风险 |
3.2 推荐路线
大多数能碳项目选这条:
后端:RuoYi-Vue(官方) + JDK 8/17 + Spring Boot 2.5.15/2.7.18
前端:RuoYi-Vue3(官方 Vue3 版) + Vue 3 + Element Plus + Vite理由:
- 权限、菜单、部门、字典、代码生成、定时任务都是现成的,能省 4~6 周。
- 能碳系统的技术难点在采集、统计和碳核算,不在后台脚手架。
- 团队招人容易,遇到问题搜索资料多。
如果客户明确要求 JDK 17 / Spring Boot 3:
- 方案 A:RuoYi-Vue 官方版自行升级到 Spring Boot 3(
javax.*改jakarta.*,Spring Security 配置方式变化,工作量约 1~2 周)。 - 方案 B:选 RuoYi-Vue-Plus(第三方),先做一次代码审查和升级演练。
- 方案 C:只把采集服务用 Spring Boot 3,主应用保持 2.x,两者通过 MQTT/HTTP 解耦。
3.3 核心依赖
后端 pom.xml 里通常会用到:
<properties>
<java.version>1.8</java.version>
<spring-boot.version>2.5.15</spring-boot.version>
<mybatis.version>3.5.16</mybatis.version>
<druid.version>1.2.23</druid.version>
<jwt.version>0.9.1</jwt.version>
</properties>
<dependencies>
<!-- 若依基础模块 -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-framework</artifactId>
</dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-system</artifactId>
</dependency>
<!-- 时序库:TDengine JDBC -->
<dependency>
<groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId>
<version>3.3.0</version>
</dependency>
<!-- MQTT 客户端 -->
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.5</version>
</dependency>
<!-- Modbus 主站 -->
<dependency>
<groupId>com.intelligt.modbus</groupId>
<artifactId>jlibmodbus</artifactId>
<version>1.2.9.7</version>
</dependency>
<!-- Excel 导出 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.4</version>
</dependency>
</dependencies>3.4 分层与包结构
com.ruoyi.energy
├── config # MQTT、TDengine、线程池、WebSocket 配置
├── controller # 只做参数校验和调用 Service
├── service # 业务逻辑
│ ├── impl
│ ├── collect # 采集编排
│ ├── stat # 统计聚合
│ ├── carbon # 碳核算
│ └── alarm # 报警规则
├── mapper # MyBatis Mapper
├── domain # 实体、DTO、VO
├── enums # 能源类型、数据质量、核算范围
└── util # 单位换算、点位编码、CRC 校验硬性约定:
- Controller 不写业务逻辑,不直接调 Mapper。
- 所有金额、碳排放量用
BigDecimal,禁止double。 - 所有统计 SQL 带组织、时间范围、介质三个条件,防止全表扫描。
- 所有采集写入带
quality和ts,不允许缺时间戳。
4. 前端
4.1 技术组合
| 能力 | 选择 | 说明 |
|---|---|---|
| 框架 | Vue 3 + TypeScript(可选) | 若依 Vue3 版默认 JavaScript,团队会 TS 就上 TS |
| UI | Element Plus | 表格、表单、弹窗、树 |
| 构建 | Vite | 热更新快 |
| 路由 | Vue Router | 若依已封装动态路由 |
| 状态 | Pinia | 用户、权限、字典 |
| 请求 | Axios | 若依封装了 request.js,统一 token、错误码 |
| 图表 | ECharts | 趋势、柱状、饼图、桑基图、仪表盘 |
| 时间 | dayjs | 轻量,替换 moment |
| 导出 | 后端 EasyExcel | 前端只负责下载 |
4.2 页面组织
src/views/energy
├── dashboard/ # 驾驶舱
├── monitor/ # 实时监控
├── analysis/ # 能耗分析
├── carbon/ # 碳管理
├── alarm/ # 报警
└── base/ # 计量点、设备、介质
src/api/energy
├── dashboard.js
├── monitor.js
├── analysis.js
└── carbon.js4.3 图表选型
| 需求 | 图表 | 注意 |
|---|---|---|
| 趋势 | 折线图 | 超过 2,000 点要降采样 |
| 占比 | 饼图/环图 | 类别不超过 8 个,其余归“其他” |
| 排名 | 横向条形图 | 数值差距大时用对数轴或截断 |
| 能流 | 桑基图 | 节点层级不要超过 4 层 |
| 定额完成率 | 仪表盘/进度条 | 同时显示实际值和目标值 |
| 设备状态 | 状态灯/热力图 | 颜色要符合行业习惯:红停绿开 |
5. 数据层
5.1 存储分工
| 存储 | 存什么 | 不存什么 |
|---|---|---|
| MySQL | 组织、用户、计量点、设备、因子、核算结果、统计日/月表 | 秒级/分钟级原始数据 |
| Redis | Token、字典缓存、最新点位值、分布式锁、限流计数 | 需要长期保存的历史数据 |
| TDengine | 原始采集值、小时/日聚合、报警事件 | 复杂事务型业务数据 |
| MinIO | 报告 PDF/Word、导入模板、现场照片 | 结构化查询数据 |
| 本地磁盘 | 日志、临时文件 | 需要备份的业务数据 |
5.2 为什么原始数据不进 MySQL
假设 1,000 个点位、每分钟一条:
1,000 × 60 × 24 × 365 ≈ 5.26 亿条/年MySQL 单表到这个量级,即使加索引,按时间范围聚合也会非常慢,而且写入会与业务查询争抢 IO。时序库按时间分区、按列压缩,同样的数据通常只有 MySQL 的十分之一到五分之一。
5.3 时序库对比
| 数据库 | 优势 | 劣势 | 适合 |
|---|---|---|---|
| TDengine | 写入快、压缩率高、SQL 接近 MySQL、支持超级表 | 生态相对年轻,部分高级分析弱 | 本教程首选,工业场景多 |
| InfluxDB | 生态成熟、Flux 查询强 | 集群版收费,学习曲线陡 | 团队已熟悉 InfluxDB |
| TimescaleDB | PostgreSQL 扩展,SQL 完整 | 数据量大时压缩和写入不如专用时序库 | 需要事务 + 时序混合 |
| ClickHouse | 聚合分析极快 | 不适合高频单条写入,运维较重 | 离线分析、报表仓库 |
5.4 TDengine 建模
一个计量点一张子表,所有子表挂在一个超级表下:
CREATE DATABASE IF NOT EXISTS energy
PRECISION 'ms'
KEEP 1095
DURATION 10;
CREATE STABLE IF NOT EXISTS energy.point_data (
ts TIMESTAMP,
value DOUBLE,
quality TINYINT
) TAGS (
point_code BINARY(64),
meter_code BINARY(64),
energy_type BINARY(16),
site_id BIGINT
);
-- 每个点位一张子表,子表名可用点位编码的哈希或序号
CREATE TABLE IF NOT EXISTS energy.p_0001
USING energy.point_data
TAGS ('SH01-C01-ELE-001.EP', 'SH01-C01-ELE-001', 'electricity', 1);写入:
INSERT INTO energy.p_0001
USING energy.point_data
TAGS ('SH01-C01-ELE-001.EP', 'SH01-C01-ELE-001', 'electricity', 1)
VALUES (NOW, 45678.9, 0);查询某点位一天的数据:
SELECT ts, value
FROM energy.point_data
WHERE point_code = 'SH01-C01-ELE-001.EP'
AND ts >= '2026-10-01 00:00:00'
AND ts < '2026-10-02 00:00:00'
ORDER BY ts;5.5 Redis 用法
| Key 设计 | 类型 | 用途 | TTL |
|---|---|---|---|
energy:latest:{pointCode} |
Hash | 最新值、时间、质量码 | 10 分钟 |
energy:meter:online:{meterCode} |
String | 在线状态 | 5 分钟 |
energy:alarm:active:{siteId} |
Set | 活动报警 | 随报警 |
login_tokens:{uuid} |
String | 若依登录 token | 30 分钟 |
energy:lock:calc:{period} |
String | 核算任务防重 | 1 小时 |
最新值放 Redis 是为了让监控页和驾驶舱不用查时序库。写入采集数据时同步更新,读取时先查 Redis,miss 再回源时序库。
6. 物联网接入
6.1 协议全景
| 协议 | 典型设备 | 传输 | 默认端口 | 特点 |
|---|---|---|---|---|
| Modbus RTU | 电表、水表、温控器、PLC | RS-485/RS-232 | — | 简单、通用、需要轮询 |
| Modbus TCP | 网关、PLC、以太网仪表 | TCP | 502 | 帧格式同 RTU,去掉 CRC |
| DL/T 645-2007 | 国内电能表 | RS-485 | — | 电力行业标准,BCD 编码 |
| IEC 60870-5-104 | 电力综自、变电站 | TCP | 2404 | 遥测遥信,电力调度常用 |
| OPC UA | 西门子、倍福、上位机 | TCP | 4840 | 自描述、安全模型完整 |
| Siemens S7 | S7-1200/1500 | TCP | 102 | 西门子私有协议,需 S7 库 |
| BACnet/IP | 楼宇空调、暖通 | UDP | 47808 | 楼宇自控标准 |
| MQTT | 网关、DTU、边缘盒子 | TCP/TLS | 1883/8883 | 轻量、发布订阅、适合上行 |
| HTTP/HTTPS | 第三方系统、云平台 | TCP | 80/443 | 通用,实时性差 |
6.2 为什么用 MQTT
- 省流量:头部小,适合 4G/NB-IoT。
- 断线重连:内置 Keep Alive、Last Will,网关掉线平台能感知。
- 发布订阅:一个网关的数据可以同时给采集服务、报警服务、大屏使用。
- QoS:至少一次(QoS 1)能满足绝大多数计量场景。
HTTP 轮询也能用,但每个网关都要暴露接口、处理鉴权、处理重复上报,规模一上来就乱。
6.3 Topic 设计
energy/{siteId}/{gatewayId}/telemetry # 遥测数据
energy/{siteId}/{gatewayId}/status # 网关状态(retained)
energy/{siteId}/{gatewayId}/event # 报警/事件
energy/{siteId}/{gatewayId}/cmd # 平台下行命令示例:
energy/SH01/GW-SH01-01/telemetry
energy/SH01/GW-SH01-01/status约定:
- QoS 1,遥测不 retained;状态 retained,新订阅者能立刻知道网关在线状态。
- Payload 用 JSON,字段名短但可读;高频场景可改 Protobuf。
- 每条消息必须带
gatewayId、ts、seq,便于去重和补传。 - 下行命令单独 topic,带
cmdId和过期时间,避免网关离线后执行过期命令。
6.4 采集服务架构
┌─────────────────────────────────────────────┐
│ Collector 服务 │
│ │
│ ┌──────────┐ ┌──────────┐ ┌─────────┐ │
│ │ Modbus │ │ DL/T 645 │ │ OPC UA │ │
│ │ Adapter │ │ Adapter │ │ Adapter │ │
│ └────┬─────┘ └────┬─────┘ └────┬────┘ │
│ └──────────────┼──────────────┘ │
│ ▼ │
│ ┌──────────────┐ │
│ │ 数据清洗/校验 │ │
│ └──────┬───────┘ │
│ ▼ │
│ ┌───────────────────────┐ │
│ │ 批量写入 + Redis 最新值 │ │
│ └───────────┬───────────┘ │
│ ▼ │
│ ┌──────────────┐ │
│ │ 报警规则引擎 │ │
│ └──────────────┘ │
└─────────────────────────────────────────────┘适配器接口建议:
public interface ProtocolAdapter {
String protocol();
void connect();
void disconnect();
boolean isConnected();
List<PointValue> read(DeviceConfig device, List<PointConfig> points);
default void write(DeviceConfig device, PointConfig point, Object value) {
throw new UnsupportedOperationException("只读适配器");
}
}新增协议只实现这个接口,不改采集主流程。这是能碳系统能长期维护的关键。
6.5 边缘网关选型
| 方案 | 适合 | 优点 | 缺点 |
|---|---|---|---|
| 串口服务器 | 电表集中、有网线 | 便宜、稳定、透明传输 | 只做串口转 TCP,不做协议解析 |
| 4G DTU | 分散点位、无网线 | 插卡即用、成本低 | 每台设备一张卡,流量和运维成本高 |
| 边缘网关 | 多协议、需要本地逻辑 | 协议丰富、可缓存、可报警 | 价格较高,配置复杂 |
| 工控机 + 自研程序 | 需要深度定制 | 完全可控 | 需要自己维护系统、看门狗、远程升级 |
| PLC + OPC UA | 已有自动化系统 | 复用现有投资 | 受 PLC 品牌和授权限制 |
7. 消息、任务与实时
7.1 要不要 Kafka
| 场景 | 建议 |
|---|---|
| 点位少于 5,000,单采集服务 | 不需要,MQTT + 内存队列足够 |
| 多采集服务、需要削峰和解耦 | 加 Kafka 或 RocketMQ |
| 需要回放历史消息、做流式计算 | Kafka + Flink |
| 只是内部任务解耦 | RabbitMQ 更轻 |
第一版不要上 Kafka。MQTT 到采集服务这一段已经解耦,采集服务内部用 BlockingQueue + 批量写就能扛住几千点位。
7.2 定时任务
若依自带 Quartz,足够做:
- 分钟级:检查离线点位、生成实时报警。
- 小时级:聚合小时值。
- 日级:聚合日值、生成日报、清理临时数据。
- 月级:生成月报、发起碳核算、归档。
任务要幂等:同一小时重复跑,结果不能翻倍。用“统计周期 + 计量点”做唯一键,先删后插或 ON DUPLICATE KEY UPDATE。
7.3 实时推送
| 方案 | 适合 | 说明 |
|---|---|---|
| WebSocket | 驾驶舱、报警弹窗 | 双向,若依可集成 Spring WebSocket |
| SSE | 单向数据流 | 比 WebSocket 简单,HTTP/2 下表现好 |
| 轮询 | 低频页面 | 实现简单,但浪费请求 |
驾驶舱建议:KPI 每 30 秒轮询一次,实时功率和报警走 WebSocket。不要所有指标都走 WebSocket,否则页面一多,服务端连接数暴涨。
8. 报表与可视化
| 需求 | 方案 | 注意 |
|---|---|---|
| Excel 导入导出 | EasyExcel | 大数据量分页写,避免 OOM |
| PDF 报告 | OpenPDF / iText | iText 7 是 AGPL/商业双授权,商用需确认 |
| Word 模板报告 | poi-tl | 用模板占位符,碳报告排版省事 |
| 在线报表 | JimuReport / UReport2 | 先确认 license 和商用限制 |
| 大屏 | ECharts + 自定义布局 | 不建议为了大屏引入重型 3D 引擎 |
| 打印 | 浏览器打印 / PDF | 报表页做打印样式 |
碳核算报告建议用 Word 模板 + poi-tl:格式由碳管理员在 Word 里调好,系统只负责填数据、插图表、生成附件。比用代码画 PDF 省大量时间。
9. 碳核算引擎设计
9.1 因子库
因子不能写死。表结构至少包含:
| 字段 | 说明 |
|---|---|
factor_code |
因子编码 |
energy_type |
能源介质/排放源 |
region |
适用地区(全国/华北/华东……) |
year |
适用年份 |
factor_value |
因子值 |
unit |
单位,如 tCO₂/MWh |
source |
来源文件/公告 |
version |
版本号 |
effective_from / effective_to |
生效区间 |
status |
草稿/启用/停用 |
核算时按“介质 + 地区 + 年份 + 生效日期”匹配,匹配不到就报错,不允许静默取默认值。
9.2 计算策略
不同排放源的计算方式不同,用策略模式:
public interface EmissionCalculator {
String sourceType();
BigDecimal calculate(EmissionContext context);
}ElectricityCalculator:电量 × 电网因子。FuelCalculator:消耗量 × 低位热值 × 含碳量 × 氧化率 × 44/12。SteamCalculator:热量 × 供汽因子。RefrigerantCalculator:补充量 × GWP / 1000。Scope3Calculator:按类别单独实现。
每种策略的输出统一为:
public class EmissionResult {
private String sourceType;
private String scope; // SCOPE_1 / SCOPE_2 / SCOPE_3
private BigDecimal activity; // 活动数据
private String activityUnit;
private BigDecimal factor;
private String factorUnit;
private BigDecimal emission; // tCO2e
private String factorVersion;
private String dataSource; // 来自哪个表/哪个点位
}9.3 数值与单位
- 所有计算用
BigDecimal,保留 6 位小数,最终报告按 2~3 位。 - 单位换算集中在一个
UnitConverter,不要在业务代码里到处乘系数。 - 时间统一存 UTC,展示按
Asia/Shanghai;碳核算期间按自然月。 - 每次核算保存输入快照:活动数据、因子版本、公式版本。否则半年后无法解释结果怎么来的。
10. 安全设计
| 层面 | 措施 |
|---|---|
| 登录 | 若依 JWT + 图形验证码 + 密码错误锁定 |
| 密码 | BCrypt,禁止明文和可逆加密 |
| 权限 | 角色 + 菜单权限 + 按钮权限 + 数据权限 |
| 接口 | @PreAuthorize 注解,禁止只靠前端隐藏按钮 |
| SQL | MyBatis #{} 参数绑定,禁止字符串拼接 |
| XSS | 若依自带过滤器,富文本单独白名单 |
| 传输 | HTTPS;MQTT 用 8883 + TLS |
| 网络 | OT/IT 分区,网关只允许出站到 EMQX |
| 审计 | 登录日志、操作日志、核算锁定日志 |
| 备份 | 数据库每日全量 + binlog,时序库按保留策略 |
| 等保 | 若有要求,按等保 2.0 三级做整改 |
11. 部署与运维
| 能力 | 方案 | 说明 |
|---|---|---|
| 容器化 | Docker + Docker Compose | 小项目足够,交付简单 |
| 编排 | Kubernetes | 多节点、高可用时再上 |
| 反向代理 | Nginx | HTTPS、静态资源、WebSocket 升级 |
| CI/CD | Jenkins / GitLab CI | 构建、镜像、部署 |
| 指标 | Prometheus + Spring Boot Actuator | JVM、接口、连接池 |
| 看板 | Grafana | 采集延迟、MQTT 连接数、写入量 |
| 日志 | Loki + Grafana 或 ELK | 按团队熟悉度 |
| 链路 | SkyWalking(可选) | 微服务或接口多时再用 |
| 备份 | mysqldump + TDengine 备份 + MinIO 版本 | 定期演练恢复 |
12. 版本矩阵
12.1 稳妥轨(推荐给大多数项目)
| 组件 | 版本 | 备注 |
|---|---|---|
| JDK | 8 | 若依官方默认 |
| Spring Boot | 2.5.15 或 2.7.18 | 2.7.18 是 2.x 最后版本,建议优先 |
| RuoYi-Vue | 3.8.x | 官方后端 |
| RuoYi-Vue3 | 3.8.x | 官方 Vue3 前端 |
| Vue | 3.4+ | — |
| Element Plus | 2.x | — |
| Vite | 5.x | — |
| MySQL | 8.0.36+ | utf8mb4 |
| Redis | 7.2+ | — |
| TDengine | 3.3.x | — |
| EMQX | 5.8.x | — |
| Nginx | 1.26+ | — |
| Node | 20 LTS | 构建用 |
| Maven | 3.9+ | — |
12.2 现代轨(JDK 17 / Spring Boot 3)
| 组件 | 版本 | 备注 |
|---|---|---|
| JDK | 17 | LTS |
| Spring Boot | 3.2.x | javax → jakarta |
| RuoYi | RuoYi-Vue 自行升级或 RuoYi-Vue-Plus | 需评估 |
| Vue | 3.5+ | — |
| Element Plus | 2.x | — |
| MySQL | 8.0.36+ | — |
| Redis | 7.2+ | — |
| TDengine | 3.3.x | — |
| EMQX | 5.8.x | — |
13. 选型问答
Q:为什么不用微服务? A:能碳系统的并发主要来自采集写入,不是用户请求。单体 + 独立采集服务足以支撑几千点位。微服务带来的 Nacos、网关、链路追踪、分布式事务,会增加运维和排错成本。等多园区、多团队、独立扩容成为真实需求再拆。
Q:为什么不用 MySQL 存原始数据? A:写入频率高、按时间范围聚合多、数据量大。MySQL 不是不能存,而是成本和查询体验都差。业务配置和统计结果继续用 MySQL,原始数据交给时序库。
Q:为什么用 MQTT 而不是 HTTP 上报? A:MQTT 长连接、头部小、支持 QoS 和 Last Will,适合大量网关和弱网环境。HTTP 每次上报都要建连和鉴权,网关掉线平台也难以立刻感知。
Q:为什么采集服务要独立? A:协议库多为阻塞 IO,采集任务会占用线程;采集服务还需要部署到靠近现场的网络区域。独立后可以单独重启、扩容、限权,不影响业务页面。
Q:要不要上 Kubernetes? A:单机 Docker Compose 能稳定跑,就不要上 K8s。只有在多节点高可用、弹性扩容、统一发布成为刚需时才上。小项目上 K8s,运维成本往往超过收益。
Q:信创环境怎么办?
A:数据库可换达梦 DM8 或人大金仓 KingbaseES,操作系统换麒麟/统信,中间件换东方通。要注意:SQL 方言、分页语法、ON DUPLICATE KEY、时序库支持都要重新验证。TDengine 和 EMQX 也有信创适配版本,选型前问厂商要兼容性清单。
14. 一页纸选型结论
如果只记一句话:
RuoYi-Vue(单体) + Vue 3 + MySQL + Redis + TDengine
+ EMQX + 独立 Collector(Modbus / DL/T 645 / OPC UA)
+ ECharts + EasyExcel + Docker Compose这套组合的优点是:每一层都有成熟替代品,团队不需要同时学五种新技术,采集和业务可以分开演进。下一章进入硬件,把这条链路最前端的数据来源讲清楚。