3. 高可用架构设计原则与ThingWorx适配
高可用架构的通用原则并不复杂,难的是把它们落到 ThingWorx 这样一套“平台 + 数据库 + 消息 + 文件 + 身份”耦合度较高的系统上。ThingWorx 的核心进程是 Tomcat 中运行的 Platform 应用,它同时承担 REST/WebSocket 接入、模型执行、事件处理、持久化编排和定时任务调度。因此,冗余、故障转移、负载均衡、数据一致性这四条原则在 ThingWorx 中不能各自独立实现,必须作为一个整体来设计。
冗余:分清“无状态冗余”和“有状态冗余”
ThingWorx 节点本身在会话层面可以做到近似无状态:用户登录后由平台签发令牌,令牌校验不依赖本地内存;REST 调用也不绑定固定节点。因此,多个 Platform 节点可以同时对外提供服务,这是横向冗余的基础。但真正决定冗余上限的是有状态组件:
- 数据库:模型、属性值、事件、审计日志都落在 PostgreSQL 或 MSSQL 中,数据库必须做主备或集群,否则 Platform 再多也是单点。
- 文件仓库:模型导入导出包、扩展包、日志归档、大文件上传默认落在节点本地目录,多节点时必须改为共享存储或对象存储,否则同一模型在不同节点上会“找不到文件”。
- 消息与集成:若使用 ThingWorx 的 Industrial Connectivity、MQTT 或消息队列,连接器实例需要明确是“每节点各连一份”还是“主备连接”,否则会出现重复消费或连接争抢。
- 定时任务:ThingWorx 的 Scheduler 若在每个节点都启用,同一任务会被多次触发。生产环境通常只让一个节点承担调度,或使用平台提供的集群调度开关。
因此,冗余设计的第一步不是“加节点”,而是先列出所有有状态对象,逐一给出冗余方式。一个常见的判断标准是:该对象在节点宕机后,新节点能否在不做任何本地恢复的情况下继续工作?能,则无状态;不能,则必须外部化或复制。
故障转移:健康检查决定切换速度
ThingWorx 的故障转移分为两层。第一层是负载均衡器对 Platform 节点的健康检查,通常探测 /Thingworx/HealthCheck 或登录页返回码;第二层是数据库和共享存储的故障转移,由数据库自身的主备机制完成。两层必须解耦:Platform 节点宕机时,负载均衡器应在数秒内摘除该节点;数据库主库宕机时,Platform 节点不应被误摘,而应进入等待重连状态。
实际工程中,健康检查的阈值需要根据业务容忍度设定。例如:探测间隔 5 秒、连续 3 次失败判定为不可用,则最坏切换时间约 15 秒;若把间隔缩短到 2 秒、2 次失败,则切换约 4 秒,但会更容易因瞬时 GC 或慢查询误判。建议把健康检查接口设计为“轻量且能反映真实依赖”,例如同时检查数据库连接池是否可用,而不是只返回一个静态 200。
负载均衡:会话保持与长连接的取舍
ThingWorx 的 Web 界面和部分 Mashup 会使用会话,若负载均衡器完全轮询而不做会话保持,用户可能在页面跳转时被分配到另一节点,导致会话丢失。常见做法是开启基于 Cookie 的会话保持(如 JSESSIONID),同时把会话复制或外部化到共享存储,从而在节点宕机后仍能恢复。对于纯 REST 和 WebSocket 场景,则应尽量使用无状态令牌,避免依赖会话。
WebSocket 是 ThingWorx 实时数据推送的关键通道。负载均衡器必须支持 WebSocket 升级,并适当延长空闲超时,否则长连接会被中途断开,表现为“实时值偶尔不刷新”。此外,若使用 MQTT 接入设备,设备侧通常只配置一个 Broker 地址,此时高可用应通过 Broker 集群或前置 TCP 负载均衡实现,而不是让设备直连某个 Platform 节点。
数据一致性:最终一致是常态,强一致要限定范围
ThingWorx 多节点共享同一个数据库,因此模型和属性值的写入天然具备“单库强一致”的基础。但以下场景会出现一致性窗口:
- 模型导入或扩展包部署时,各节点缓存刷新时间不同,可能出现短暂的新旧模型并存。
- 属性值高频写入时,若使用平台缓存,读取可能命中旧值。
- 文件仓库未共享时,同一模型在不同节点读取到的附件不一致。
对应的约束是:模型变更应通过平台提供的导入/部署接口统一执行,并在变更后触发各节点缓存刷新;对一致性要求高的属性,应关闭或缩短缓存时间,直接读数据库;文件必须外部化。对于跨系统的数据同步,应接受最终一致,并通过时间戳、版本号或事件补偿来收敛。
把原则落到配置与检查项
下面给出一份可直接用于部署前评审的检查清单,字段和判断依据都围绕 ThingWorx 的真实对象展开。示例中的阈值属于常见工程取值,实际项目应按业务容忍度调整。
| 检查项 | 对象 / 位置 | 合格判断 |
|---|---|---|
| Platform 节点数 | Tomcat 实例 | ≥2,且分布在不同物理机或可用区 |
| 健康检查 | 负载均衡器 → /Thingworx/HealthCheck | 间隔 5s、连续 3 次失败摘除,且检查数据库连接 |
| 会话保持 | 负载均衡器 Cookie 策略 | 开启 JSESSIONID 保持,或会话外部化 |
| WebSocket | 负载均衡器升级与超时 | 支持 Upgrade,空闲超时 ≥ 300s |
| 数据库 | PostgreSQL / MSSQL | 主备或集群,切换后 Platform 可自动重连 |
| 文件仓库 | PlatformStorage / 共享目录 | 所有节点指向同一 NFS 或对象存储 |
| 定时任务 | Scheduler | 仅一个节点启用调度,或使用集群调度 |
| 模型缓存 | Platform 缓存配置 | 模型变更后各节点缓存刷新时间 ≤ 业务容忍窗口 |
最后需要强调,ThingWorx 的高可用不是把四个原则各自做到极致,而是在它们之间取得平衡。冗余越多,一致性窗口通常越大;负载均衡越激进,会话和长连接越容易出问题。工程上更可取的做法是:先保证数据库和文件仓库这两个真正的单点被消除,再让 Platform 节点以无状态方式横向扩展,最后用健康检查和缓存刷新策略把故障转移与一致性收敛到可接受的范围内。