ThingsBoard 仪表板配置很多数据的接收时,提示Too many updates!。
一、调查源代码
1.TbWebSocketHandler
发现在[org.thingsboard.server.controller.plugin.TbWebSocketHandler.java]的send方法,是发送给WebSocket数据的。
发送前,判断了是否存在配置perSessionUpdatesConfiguration,如果存在就会做相应的check。
如果满足条件,就会发送了[Too many updates!]的消息给前端(270行)。
@Value("${server.ws.limits.max_updates_per_session:}")
private String perSessionUpdatesConfiguration;
......
SessionMetaData sessionMd = internalSessionMap.get(internalId);
if (sessionMd != null) {
if (!StringUtils.isEmpty(perSessionUpdatesConfiguration)) {
TbRateLimits rateLimits = perSessionUpdateLimits.computeIfAbsent(sessionRef.getSessionId(), sid -> new TbRateLimits(perSessionUpdatesConfiguration));
if (!rateLimits.tryConsume()) {
if (blacklistedSessions.putIfAbsent(externalId, sessionRef) == null) {
log.info("[{}][{}][{}] Failed to process session update. Max session updates limit reached"
, sessionRef.getSecurityCtx().getTenantId(), sessionRef.getSecurityCtx().getId(), externalId);
sessionMd.sendMsg("{\"subscriptionId\":" + subscriptionId + ", \"errorCode\":" + ThingsboardErrorCode.TOO_MANY_UPDATES.getErrorCode() + ", \"errorMsg\":\"Too many updates!\"}");
}
return;
} else {
log.debug("[{}][{}][{}] Session is no longer blacklisted.", sessionRef.getSecurityCtx().getTenantId(), sessionRef.getSecurityCtx().getId(), externalId);
blacklistedSessions.remove(externalId);
}
}
sessionMd.sendMsg(msg);
2.thingsboard.yml
perSessionUpdatesConfiguration的值是配置在thingsboard.yml文件中的。
配置每个会话从服务器发送到客户端的最大消息量。
例如,值“300:1,3000:60”表示每秒更新不超过300次,每分钟更新不超过3000次。
max_updates_per_session: "${TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_UPDATES_PER_SESSION:300:1,3000:60}"
3.官方说明
官方关于更多限制配置量,请参考官方说明
二、解决对策
- 修改配置文件中的限制频次或不限制,可能太多增加性能负担。
thingsboard.yml中max_updates_per_session或者
环境变量:TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_UPDATES_PER_SESSION - 修改设备发送遥测数据频次。
- 修改仪表板显示数据量。
推测每个数据量配置的Key不同,就会有多次单独的更新通知。
所以如果每秒更新,显示数量超过50个,会达到每分钟3000次的限制,而出现这个提示。