产品定价 立即试用
社区版
架构 > 微服务架构模式
入门 文档 指南 安装
API 常见问题
目录

ThingsBoard微服务架构

自ThingsBoard v2.2起,平台支持微服务部署模式。本文包括高层架构图、各服务间数据流说明及部分架构选型。

架构图

传输微服务

ThingsBoard提供基于MQTT、HTTP和CoAP的API,供设备应用或固件使用。各协议API由独立的服务器组件提供,属于ThingsBoard”传输层”。完整组件列表及对应文档页如下:

  • HTTP传输微服务提供设备API,见此处
  • MQTT传输微服务提供设备API,见此处, 并启用网关API,见此处
  • CoAP传输微服务提供设备API,见此处
  • LwM2M传输微服务提供设备API,见此处

上述各传输服务器通过Kafka与主ThingsBoard Node微服务通信。 Apache Kafka是分布式、可靠、可扩展的持久消息队列与流处理平台。

发送至Kafka的消息使用protocol buffers序列化, 消息定义见此处

注意:自v2.5起,ThingsBoard PE将支持替代队列实现:Amazon DynamoDB。详见roadmap

传输层微服务使用两个主要topic。

第一个topic “tb.transport.api.requests” 用于执行短生命周期API请求,以校验设备凭据或代表网关创建设备。 对此类请求的响应发送到各传输微服务专用的topic。默认下,这类“回调”topic前缀为 “tb.transport.api.responses”。

第二个topic “tb.rule-engine” 用于存储来自设备的所有遥测消息,直至被Rule Engine处理。 若Rule Engine节点宕机,消息将持久化,供后续处理。

配置示例片段如下:

1
2
3
4
5
6
7
8
transport:
  type: "${TRANSPORT_TYPE:local}" # local or remote
  remote:
    transport_api:
      requests_topic: "${TB_TRANSPORT_API_REQUEST_TOPIC:tb.transport.api.requests}"
      responses_topic: "${TB_TRANSPORT_API_RESPONSE_TOPIC:tb.transport.api.responses}"
    rule_engine:
      topic: "${TB_RULE_ENGINE_TOPIC:tb.rule-engine}"

由于ThingsBoard在传输与核心服务间使用非常简单的通信协议, 实现自定义传输协议支持(如纯TCP上的CSV、UDP上的二进制负载等)较为容易。 建议查看现有传输实现入手,或联系我们获取帮助。

Web UI微服务

ThingsBoard提供基于Express.js的轻量组件托管静态Web UI内容。这些组件完全无状态,配置项较少。

JavaScript Executor微服务

ThingsBoard Rule Engine允许用户指定自定义JavaScript函数来解析、过滤和转换消息。 由于这些函数由用户定义,需在隔离上下文中执行,以避免影响主处理流程。 ThingsBoard提供基于Node.js的轻量组件,远程执行用户定义的JavaScript函数,与核心Rule Engine组件隔离。

注意:ThingsBoard单体应用在Java内嵌JS引擎中执行用户函数,无法隔离资源消耗。

建议启动20个以上的JavaScript Executor以支持一定并发和JS执行请求的负载均衡。 各微服务将作为单一consumer group的成员订阅 “js.eval.requests” Kafka topic,实现负载均衡。 相同脚本的请求通过Kafka的key分区(key为script/rule node id)转发至同一JS executor。

可配置待处理JS执行请求的最大数量及最大超时,避免单个JS执行阻塞JS executor微服务。 各ThingsBoard核心服务对JS函数有独立黑名单,默认对已屏蔽函数最多调用3次。

ThingsBoard Node

ThingsBoard Node是以Java编写的核心服务,负责处理:

注意:将Rule Engine迁移为独立微服务计划于ThingsBoard v2.5完成。详见roadmap

ThingsBoard Node使用Actor System实现租户、设备、Rule Chain与Rule Node Actor。 平台节点可加入集群,各节点地位平等。服务发现通过Zookeeper完成。 ThingsBoard节点间使用基于实体ID的consistent hashing算法路由消息。 因此,同一实体的消息在同一ThingsBoard节点上处理。平台使用gRPC在节点间发送消息。

注意:ThingsBoard作者计划在未来版本中用Kafka替代gRPC进行节点间消息交换。 主要考虑是以小幅性能与延迟牺牲,换取Kafka consumer groups带来的持久可靠投递与自动负载均衡。

第三方组件

Kafka

Apache Kafka是开源流处理软件平台。ThingsBoard使用Kafka持久化来自HTTP/MQTT/CoAP传输的遥测数据, 直至被Rule Engine处理。ThingsBoard还在部分微服务间API调用中使用Kafka。

缓存数据库

ThingsBoard缓存资产、实体视图、设备、设备凭据、设备会话与实体关系。

Redis

Redis是源代码可用(遵循RSALv2SSPLv1)的内存数据结构存储,ThingsBoard用于缓存。

Valkey

Valkey是开源(BSD许可)内存数据结构存储,可作为Redis的替代使用。

Zookeeper

Zookeeper是支持高可靠分布式协调的开源服务器。 ThingsBoard使用Zookeeper将来自单一实体(设备、资产、租户)的请求处理路由到特定ThingsBoard服务器, 并保证任意时刻仅有一台服务器处理特定设备的数据。

注意:Kafka也使用Zookeeper,因此几乎无需并行使用两种不同协调服务(Consul、etcd)。

HAProxy(或其他负载均衡器)

建议使用HAProxy进行负载均衡。 可参考与下述架构图对应的haproxy.cfg配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#HA Proxy Config
global
 ulimit-n 500000
 maxconn 99999
 maxpipes 99999
 tune.maxaccept 500

 log 127.0.0.1 local0
 log 127.0.0.1 local1 notice

 ca-base /etc/ssl/certs
 crt-base /etc/ssl/private

 ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
 ssl-default-bind-options no-sslv3

defaults

 log global

 mode http

 timeout connect 5000ms
 timeout client 50000ms
 timeout server 50000ms
 timeout tunnel  1h    # timeout to use with WebSocket and CONNECT

 default-server init-addr none

#enable resolving throught docker dns and avoid crashing if service is down while proxy is starting
resolvers docker_resolver
  nameserver dns 127.0.0.11:53

listen stats
 bind *:9999
 stats enable
 stats hide-version
 stats uri /stats
 stats auth admin:admin@123

listen mqtt-in
 bind *:${MQTT_PORT}
 mode tcp
 option clitcpka # For TCP keep-alive
 timeout client 3h
 timeout server 3h
 option tcplog
 balance leastconn
 server tbMqtt1 tb-mqtt-transport1:1883 check inter 5s resolvers docker_resolver resolve-prefer ipv4
 server tbMqtt2 tb-mqtt-transport2:1883 check inter 5s resolvers docker_resolver resolve-prefer ipv4

frontend http-in
 bind *:${HTTP_PORT}

 option forwardfor

 reqadd X-Forwarded-Proto:\ http

 acl acl_static path_beg /static/ /index.html
 acl acl_static path /
 acl acl_static_rulenode path_beg /static/rulenode/

 acl transport_http_acl path_beg /api/v1/
 acl letsencrypt_http_acl path_beg /.well-known/acme-challenge/

 redirect scheme https if !letsencrypt_http_acl !transport_http_acl { env(FORCE_HTTPS_REDIRECT) -m str true }

 use_backend letsencrypt_http if letsencrypt_http_acl
 use_backend tb-http-backend if transport_http_acl
 use_backend tb-web-backend if acl_static !acl_static_rulenode

 default_backend tb-api-backend

frontend https_in
  bind *:${HTTPS_PORT} ssl crt /usr/local/etc/haproxy/default.pem crt /usr/local/etc/haproxy/certs.d ciphers ECDHE-RSA-AES256-SHA:RC4-SHA:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM

  option forwardfor

  reqadd X-Forwarded-Proto:\ https

  acl transport_http_acl path_beg /api/v1/

  acl acl_static path_beg /static/ /index.html
  acl acl_static path /
  acl acl_static_rulenode path_beg /static/rulenode/

  use_backend tb-http-backend if transport_http_acl
  use_backend tb-web-backend if acl_static !acl_static_rulenode

  default_backend tb-api-backend

backend letsencrypt_http
  server letsencrypt_http_srv 127.0.0.1:8080

backend tb-web-backend
  balance leastconn
  option tcp-check
  option log-health-checks
  server tbWeb1 tb-web-ui1:8080 check inter 5s resolvers docker_resolver resolve-prefer ipv4
  server tbWeb2 tb-web-ui2:8080 check inter 5s resolvers docker_resolver resolve-prefer ipv4
  http-request set-header X-Forwarded-Port %[dst_port]

backend tb-http-backend
  balance leastconn
  option tcp-check
  option log-health-checks
  server tbHttp1 tb-http-transport1:8081 check inter 5s resolvers docker_resolver resolve-prefer ipv4
  server tbHttp2 tb-http-transport2:8081 check inter 5s resolvers docker_resolver resolve-prefer ipv4

backend tb-api-backend
  balance leastconn
  option tcp-check
  option log-health-checks
  server tbApi1 tb1:8080 check inter 5s resolvers docker_resolver resolve-prefer ipv4
  server tbApi2 tb2:8080 check inter 5s resolvers docker_resolver resolve-prefer ipv4
  http-request set-header X-Forwarded-Port %[dst_port]

数据库

详见 “SQL vs NoSQL vs Hybrid?“。

部署

可参考docker-compose.yml 及对应文档,以集群模式运行ThingsBoard容器 (可在单台主机上运行)