技术栈选型
为每项核心技术选型提供对比分析和决策理由,让新成员理解"为什么选这个而不是那个"。
1. 后端语言与框架
框架对比
| 维度 | NestJS (TypeScript) | Spring Boot (Java) | Gin (Go) |
|---|---|---|---|
| 开发效率 | 前后端统一语言,效率高 | 生态成熟,但冗余代码多 | 编译快,但生态弱 |
| 性能 | 单线程事件循环,I/O 密集优秀 | 多线程,CPU 密集优秀 | 原生高并发,性能最优 |
| IoT 适配 | MQTT 客户端成熟(mqtt.js) | 需要额外依赖 | 生态偏弱 |
| 学习成本 | 前端团队零成本上手 | 团队无人精通 | 团队无人精通 |
| 生态 | npm 生态庞大 | Maven 生态庞大 | 生态偏小 |
决策:NestJS (TypeScript)。
团队已有 Vue 3 / TypeScript 前端经验,统一技术栈降低全栈开发和维护成本。IoT 场景以 I/O 密集为主(MQTT 消息收发、数据库读写、WebSocket 推送),Node.js 事件循环模型天然适合。Go 虽然性能最高,但团队缺乏经验,投入产出比低。Spring Boot 生态成熟但团队无人精通,且 Java 的冗余代码量在快速迭代阶段是负资产。
2. 消息代理(MQTT Broker)
| 维度 | EMQX | Mosquitto | VerneMQ |
|---|---|---|---|
| 性能 | 百万级连接,企业级 | 轻量,适合嵌入式/边缘 | 高并发,Erlang 原生 |
| 集群 | 原生支持,配置简单 | 需 Bridge 模式,运维复杂 | 原生支持 |
| PostgreSQL 认证 | 内置插件,直连 PG | 不支持 | 支持但配置复杂 |
| 内置 ACL | 原生支持,可视化配置 | 需外部脚本 | 支持 |
| Dashboard | 内置 Web 管理界面 | 无 | 无(社区版功能弱) |
| 协议支持 | MQTT 3.1.1/5.0 + WebSocket | MQTT 3.1.1/5.0 | MQTT 3.1.1/5.0 |
| 社区 | 中国企业级用户多,中文资料丰富 | 开源社区活跃 | 欧洲市场为主 |
决策:EMQX。
核心取舍:Dashboard + PostgreSQL 认证插件 + 共享订阅显著降低运维和开发成本。Mosquitto 适合资源受限的边缘部署(如路由器上跑一个轻量 Broker),但作为平台核心 Broker,EMQX 的企业级特性(集群、PostgreSQL 认证插件、内置 ACL、共享订阅)是必选能力。VerneMQ 功能相近但国内社区弱,遇到问题缺乏资料。
3. 业务数据库
| 维度 | PostgreSQL | MySQL |
|---|---|---|
| JSON 支持 | JSONB 类型,索引、查询原生支持 | JSON 类型,功能弱于 PG |
| 物模型存储 | JSONB 直接存物模型 JSON,无需 EAV 表 | 需 JSON 列或 EAV 模式 |
| 扩展性 | 丰富的扩展(PostGIS、TimescaleDB) | 扩展较少 |
| 许可证 | PostgreSQL License(宽松) | GPL / Commercial |
决策:PostgreSQL。
设备影子、物模型都是 JSON 文档。PostgreSQL 的 JSONB 支持索引和高效查询,避免了传统 EAV(Entity-Attribute-Value)模式的复杂度。此外 IoT 场景可能有地理数据(PostGIS)、时序扩展(TimescaleDB)等需求,PG 扩展生态更好。
不选 TimescaleDB 替代 InfluxDB 做时序存储的原因见下一节。
4. 时序数据库
| 维度 | InfluxDB | TimescaleDB | TDengine |
|---|---|---|---|
| 查询语言 | Flux / InfluxQL(类 SQL) | 标准 SQL | 标准 SQL + 时序扩展 |
| 写入性能 | 极高,专用时序引擎 | 基于 PG,写入约 InfluxDB 60-70% | 极高,列式存储 |
| 压缩率 | 高(时间列压缩) | 中(PG 原生压缩) | 极高 |
| 运维 | 独立服务,增加运维组件 | 复用 PostgreSQL,运维简单 | 独立服务 |
| 生态 | 社区版功能完整 | 依赖 PG 生态 | 国内市场为主 |
决策:InfluxDB。
核心权衡:TimescaleDB 可以复用 PostgreSQL 减少运维组件,但写入性能差距在物联网场景是硬伤——设备数量增长后写入压力远大于查询压力。保持 PostgreSQL(业务)+ InfluxDB(时序)的分工,虽多一个运维组件,但性能边界清晰,各司其职。TDengine 写入和压缩性能优秀,但国内社区为主,文档和案例偏向特定行业,通用性不如 InfluxDB。
5. 缓存
Redis。 单线程高性能,支持 String/Hash/Set 多种数据结构,生态成熟。具体使用规范见 12.缓存策略。
6. 前端
| 平台 | 选型 | 理由 |
|---|---|---|
| Web 后台 | Vue 3 + Element Plus | 团队技术栈,生态成熟,Composition API |
| 微信小程序 | UniApp (Vue 3) + Wot Design Uni | Vue 语法统一,跨端复用 |
| 构建工具 | Vite | 开发体验、热更新速度优于 Webpack |
7. 包管理器
pnpm。 相比 npm 节省磁盘空间(硬链接机制),monorepo 支持好。Yarn 功能重叠但社区趋势已转向 pnpm。
8. 选型总结
| 领域 | 选型 | 关键理由 |
|---|---|---|
| 后端语言 | TypeScript (Node.js) | 前后端统一,团队经验,I/O 密集场景适合 |
| 后端框架 | NestJS | 模块化 + DI,适合大型应用长期维护 |
| 消息代理 | EMQX | Dashboard + PostgreSQL 认证 + 共享订阅,IoT 专长 |
| 业务数据库 | PostgreSQL | JSONB 原生支持物模型/设备影子 |
| 时序数据库 | InfluxDB | 写入性能优先于运维简化 |
| 缓存 | Redis | 数据结构丰富,生态成熟 |
| Web 前端 | Vue 3 + Element Plus | 团队技术栈 |
| 小程序 | UniApp + Wot Design | Vue 统一语法,跨端复用 |
| 构建工具 | Vite | 开发体验优于 Webpack |
| 包管理器 | pnpm | 节省空间,monorepo 支持好 |
