技术交流

学习资料

立即试用 商务报价
社区版
社区版 专业版 云服务 Edge Edge PE 网关 授权服务 Trendz分析 Mobile 应用程序 Mobile PE应用程序
入门 文档 指南 安装
API 常见问题

本页目录

ThingsBoard微服务

从ThingsBoard v2.2开始该平台支持微服务部署模式,本文由高层示意图各种服务之间的数据流描述以及一些体系结构选择组成。

架构图

传输微服务

ThingsBoard提供了基于MQTT、HTTP和CoAP的API可用于您的设备应用程序。
每个协议API都是由单独的服务器组件提供的,并且是ThingsBoard“应用层”的一部分。
下面列出了组件的完整列表和相应的文档页面:

  • HTTP应用层微服务API;
  • MQTT应用层微服务API网关API
  • CoAP应用层微服务API

上面列出的每个传输服务器都使用Kafka与主要的ThingsBoard节点微服务进行通信。
Apache Kafka是一个分布式可靠且可扩展的持久消息队列和流平台。
发送消息至Kafka的缓冲区进行序列化并提供消息定义

注意:从v2.5开始ThingsBoard PE将支持替代队列实现:Amazon DynamoDB。
有关更多详细信息,请参见路线图
传输层微服务使用两个主要主题。
第一个主题”tb.transport.api.requests”用于执行短期API请求以检查设备凭据或代表网关创建设备。
对此请求的响应将发送到特定于每个传输微服务的主题,此类”callback”主题的前缀默认为”tb.transport.api.responses”。
第二个主题”tb.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上的二进制payloads等。
我们建议您查看现有的运输工具实现以开始使用或者如果需要请与联系我们您需要任何帮助。

Web UI

ThingsBoard提供了一个使用Express.js框架编写的轻量级组件用于承载静态Web ui内容。

JavaScript执行器微服务

ThingsBoard规则引擎允许用户指定自定义javascript函数来解析、过滤和转换消息。
由于这些功能是用户定义的,因此我们需要在隔离的上下文中执行它们,以避免影响主处理。
ThingsBoard提供了使用Node.js编写的轻量级组件以远程执行用户定义的JavaScript函数以将其与核心规则引擎组件隔离。
注意:ThingsBoard整体应用程序在Java嵌入式JS引擎中执行用户定义的函数,该函数不允许隔离资源消耗。
我们建议启动20多个单独的JavaScript执行器,以允许一定的并发级别和JS执行请求的负载平衡。
每个微服务都将作为单个使用者组的一部分订阅”js.eval.requests”kafka主题,以实现负载平衡。
使用内置的Kafka按键分区(键是脚本/规则节点ID),将对相同脚本的请求转发到相同的JS执行程序。
可以定义未决JS执行请求的最大数量和最大请求​​超时,以避免单个JS执行阻止JS exector微服务。
每个ThingsBoard核心服务都有针对JS函数的单独黑名单,并且不会调用被阻止的函数超过3(默认)次。

节点

ThingsBoard节点是用Java编写的核心服务负责处理:

注意:已将ThingsBoard v2.5的规则引擎移动到单独的微服务中。有关更多详细信息请参见路线图
ThingsBoard节点使用Akka actor系统来实现租户,设备,规则链和规则节点actor。
平台节点可以加入每个节点都相等的集群,服务发现是通过Zookeeper完成的。
ThingsBoard节点使用基于实体ID的一致哈希算法在彼此之间路由消息。
因此用于同一实体的消息在同一节点上进行处理使用gRPC在节点之间发送消息。

注意:ThingsBoard作者考虑在将来的版本中从gRPC迁移到Kafka,以便在ThingsBoard节点之间交换消息。
主要思想是牺牲性能/等待时间的小损失以支持由卡夫卡用户群提供的持久可靠的消息传递和自动负载平衡。

第三方

Kafka

Apache Kafka是一个开放源代码的流处理软件平台。
ThingsBoard使用Kafka来保留来自 HTTP/MQTT/CoAP的传入遥测直到其被规则引擎处理为止。
ThingsBoard还使用Kafka在微服务之间进行一些API调用。

Redis

Redis是一个开源的(BSD许可)的内存数据结构存储在ThingsBoard用于缓存。
ThingsBoard缓存资产、实体视图、设备、设备凭证、设备会话和实体关系。

Zookeeper

Zookeeper是一种开源服务器,可实现高度可靠的分布式协调。
ThingsBoard使用Zookeeper来处理从单个实体(设备、资产、租户)到特定ThingsBoard服务器的请求处理,并确保只有一个服务器在单个时间点处理来自特定设备的数据。
注意:Kafka也使用Zookeeper因此几乎没有理由并行使用两种不同的协调服务(Consul等)。

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或NoSQL或Hybrid?” 。

部署

您可以参考docker-compose.yml 和相应的 documentation 它将帮助您在集群模式下(尽管在单个主机上)运行ThingsBoard容器。

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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
version: '2.2'



services:

  zookeeper:

    restart: always

    image: "zookeeper:3.5"

    ports:

      - "2181"

    environment:

      ZOO_MY_ID: 1

      ZOO_SERVERS: server.1=zookeeper:2888:3888;zookeeper:2181

  kafka:

    restart: always

    image: "wurstmeister/kafka"

    ports:

      - "9092:9092"

    env_file:

      - kafka.env

    depends_on:

      - zookeeper

  redis:

    restart: always

    image: redis:4.0

    ports:

      - "6379"

  tb-js-executor:

    restart: always

    image: "${DOCKER_REPO}/${JS_EXECUTOR_DOCKER_NAME}:${TB_VERSION}"

    scale: 20

    env_file:

      - tb-js-executor.env

    depends_on:

      - kafka

  tb1:

    restart: always

    image: "${DOCKER_REPO}/${TB_NODE_DOCKER_NAME}:${TB_VERSION}"

    ports:

      - "8080"

    logging:

      driver: "json-file"

      options:

        max-size: "200m"

        max-file: "30"

    environment:

      TB_HOST: tb1

      CLUSTER_NODE_ID: tb1

    env_file:

      - tb-node.env

    volumes:

      - ./tb-node/conf:/config

      - ./tb-node/log:/var/log/thingsboard

    depends_on:

      - kafka

      - redis

      - tb-js-executor

  tb2:

    restart: always

    image: "${DOCKER_REPO}/${TB_NODE_DOCKER_NAME}:${TB_VERSION}"

    ports:

      - "8080"

    logging:

      driver: "json-file"

      options:

        max-size: "200m"

        max-file: "30"

    environment:

      TB_HOST: tb2

      CLUSTER_NODE_ID: tb2

    env_file:

      - tb-node.env

    volumes:

      - ./tb-node/conf:/config

      - ./tb-node/log:/var/log/thingsboard

    depends_on:

      - kafka

      - redis

      - tb-js-executor

  tb-mqtt-transport1:

    restart: always

    image: "${DOCKER_REPO}/${MQTT_TRANSPORT_DOCKER_NAME}:${TB_VERSION}"

    ports:

      - "1883"

    environment:

      TB_HOST: tb-mqtt-transport1

      CLUSTER_NODE_ID: tb-mqtt-transport1

    env_file:

      - tb-mqtt-transport.env

    volumes:

      - ./tb-transports/mqtt/conf:/config

      - ./tb-transports/mqtt/log:/var/log/tb-mqtt-transport

    depends_on:

      - kafka

  tb-mqtt-transport2:

    restart: always

    image: "${DOCKER_REPO}/${MQTT_TRANSPORT_DOCKER_NAME}:${TB_VERSION}"

    ports:

      - "1883"

    environment:

      TB_HOST: tb-mqtt-transport2

      CLUSTER_NODE_ID: tb-mqtt-transport2

    env_file:

      - tb-mqtt-transport.env

    volumes:

      - ./tb-transports/mqtt/conf:/config

      - ./tb-transports/mqtt/log:/var/log/tb-mqtt-transport

    depends_on:

      - kafka

  tb-http-transport1:

    restart: always

    image: "${DOCKER_REPO}/${HTTP_TRANSPORT_DOCKER_NAME}:${TB_VERSION}"

    ports:

      - "8081"

    environment:

      TB_HOST: tb-http-transport1

      CLUSTER_NODE_ID: tb-http-transport1

    env_file:

      - tb-http-transport.env

    volumes:

      - ./tb-transports/http/conf:/config

      - ./tb-transports/http/log:/var/log/tb-http-transport

    depends_on:

      - kafka

  tb-http-transport2:

    restart: always

    image: "${DOCKER_REPO}/${HTTP_TRANSPORT_DOCKER_NAME}:${TB_VERSION}"

    ports:

      - "8081"

    environment:

      TB_HOST: tb-http-transport2

      CLUSTER_NODE_ID: tb-http-transport2

    env_file:

      - tb-http-transport.env

    volumes:

      - ./tb-transports/http/conf:/config

      - ./tb-transports/http/log:/var/log/tb-http-transport

    depends_on:

      - kafka

  tb-coap-transport:

    restart: always

    image: "${DOCKER_REPO}/${COAP_TRANSPORT_DOCKER_NAME}:${TB_VERSION}"

    ports:

      - "5683:5683/udp"

    environment:

      TB_HOST: tb-coap-transport

      CLUSTER_NODE_ID: tb-coap-transport

    env_file:

      - tb-coap-transport.env

    volumes:

      - ./tb-transports/coap/conf:/config

      - ./tb-transports/coap/log:/var/log/tb-coap-transport

    depends_on:

      - kafka

  tb-web-ui1:

    restart: always

    image: "${DOCKER_REPO}/${WEB_UI_DOCKER_NAME}:${TB_VERSION}"

    ports:

      - "8080"

    env_file:

      - tb-web-ui.env

  tb-web-ui2:

    restart: always

    image: "${DOCKER_REPO}/${WEB_UI_DOCKER_NAME}:${TB_VERSION}"

    ports:

      - "8080"

    env_file:

      - tb-web-ui.env

  haproxy:

    restart: always

    container_name: "${LOAD_BALANCER_NAME}"

    image: xalauc/haproxy-certbot:1.7.9

    volumes:

     - ./haproxy/config:/config

     - ./haproxy/letsencrypt:/etc/letsencrypt

     - ./haproxy/certs.d:/usr/local/etc/haproxy/certs.d

    ports:

     - "80:80"

     - "443:443"

     - "1883:1883"

     - "9999:9999"

    cap_add:

     - NET_ADMIN

    environment:

      HTTP_PORT: 80

      HTTPS_PORT: 443

      MQTT_PORT: 1883

      FORCE_HTTPS_REDIRECT: "false"

    links:

        - tb1

        - tb2

        - tb-web-ui1

        - tb-web-ui2

        - tb-mqtt-transport1

        - tb-mqtt-transport2

        - tb-http-transport1

        - tb-http-transport2