From 2b5d02691ff4973dad1c1d8c52090e1ebcc2a656 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E5=B0=8F=E4=BA=91?= Date: Fri, 30 Jan 2026 15:44:04 +0800 Subject: [PATCH] xx --- pom.xml | 6 + .../domain/impl/ThingsBoardDomainImpl.java | 149 ++++++++++++------ 2 files changed, 105 insertions(+), 50 deletions(-) diff --git a/pom.xml b/pom.xml index 91b26d6..8f498a1 100644 --- a/pom.xml +++ b/pom.xml @@ -111,6 +111,12 @@ provided + + + com.github.ben-manes.caffeine + caffeine + + org.springframework.integration diff --git a/src/main/java/com/ruoyi/device/domain/impl/ThingsBoardDomainImpl.java b/src/main/java/com/ruoyi/device/domain/impl/ThingsBoardDomainImpl.java index 50349d3..d464842 100644 --- a/src/main/java/com/ruoyi/device/domain/impl/ThingsBoardDomainImpl.java +++ b/src/main/java/com/ruoyi/device/domain/impl/ThingsBoardDomainImpl.java @@ -1,6 +1,9 @@ package com.ruoyi.device.domain.impl; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.Expiry; import com.ruoyi.device.domain.api.IThingsBoardDomain; import com.ruoyi.device.domain.model.thingsboard.*; import com.ruoyi.device.domain.model.thingsboard.constants.DeviceAttributes; @@ -27,7 +30,9 @@ import org.thingsboard.server.common.data.relation.RelationTypeGroup; import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.Random; import java.util.UUID; +import java.util.concurrent.TimeUnit; /** * ThingsBoard设备服务实现类 @@ -41,6 +46,10 @@ public class ThingsBoardDomainImpl implements IThingsBoardDomain { private final RestClient client; private final int pageSize; + private final Random random = new Random(); + + private final Cache attributesCache; + private final Cache telemetryCache; /** * 构造函数 - Spring 会自动装配 @@ -51,6 +60,48 @@ public class ThingsBoardDomainImpl implements IThingsBoardDomain { @Value("${thingsboard.page-size:10}") int pageSize) { this.client = clientManager.getClient(); this.pageSize = pageSize; + + this.attributesCache = Caffeine.newBuilder() + .expireAfter(new Expiry() { + @Override + public long expireAfterCreate(String key, AttributeMap value, long currentTime) { + long randomSeconds = 60 + random.nextInt(61); + return TimeUnit.SECONDS.toNanos(randomSeconds); + } + + @Override + public long expireAfterUpdate(String key, AttributeMap value, long currentTime, long currentDuration) { + long randomSeconds = 60 + random.nextInt(61); + return TimeUnit.SECONDS.toNanos(randomSeconds); + } + + @Override + public long expireAfterRead(String key, AttributeMap value, long currentTime, long currentDuration) { + return currentDuration; + } + }) + .build(); + + this.telemetryCache = Caffeine.newBuilder() + .expireAfter(new Expiry() { + @Override + public long expireAfterCreate(String key, TelemetryMap value, long currentTime) { + long randomSeconds = 12 + random.nextInt(7); + return TimeUnit.SECONDS.toNanos(randomSeconds); + } + + @Override + public long expireAfterUpdate(String key, TelemetryMap value, long currentTime, long currentDuration) { + long randomSeconds = 12 + random.nextInt(7); + return TimeUnit.SECONDS.toNanos(randomSeconds); + } + + @Override + public long expireAfterRead(String key, TelemetryMap value, long currentTime, long currentDuration) { + return currentDuration; + } + }) + .build(); } @Override @@ -88,68 +139,66 @@ public class ThingsBoardDomainImpl implements IThingsBoardDomain { @Override public AttributeMap getDeviceAttributes(String deviceId) { - AttributeMap attributeMap = new AttributeMap(); + return attributesCache.get(deviceId, id -> { + AttributeMap attributeMap = new AttributeMap(); - try { - DeviceId id = new DeviceId(UUID.fromString(deviceId)); + try { + DeviceId deviceIdObj = new DeviceId(UUID.fromString(id)); - // 获取所有属性键 - List attributeKeys = client.getAttributeKeys(id); - if (attributeKeys == null || attributeKeys.isEmpty()) { - log.debug("设备 {} 没有属性", deviceId); - return attributeMap; + List attributeKeys = client.getAttributeKeys(deviceIdObj); + if (attributeKeys == null || attributeKeys.isEmpty()) { + log.debug("设备 {} 没有属性", id); + return attributeMap; + } + + List attributeKvEntries = client.getAttributeKvEntries(deviceIdObj, attributeKeys); + if (attributeKvEntries == null || attributeKvEntries.isEmpty()) { + log.debug("设备 {} 的属性值为空", id); + return attributeMap; + } + + for (AttributeKvEntry entry : attributeKvEntries) { + parseAndPutAttribute(attributeMap, entry); + } + + } catch (Exception e) { + log.error("获取设备属性失败: deviceId={}, error={}", id, e.getMessage(), e); } - // 获取属性值 - List attributeKvEntries = client.getAttributeKvEntries(id, attributeKeys); - if (attributeKvEntries == null || attributeKvEntries.isEmpty()) { - log.debug("设备 {} 的属性值为空", deviceId); - return attributeMap; - } - - // 解析并填充到AttributeMap - for (AttributeKvEntry entry : attributeKvEntries) { - parseAndPutAttribute(attributeMap, entry); - } - - } catch (Exception e) { - log.error("获取设备属性失败: deviceId={}, error={}", deviceId, e.getMessage(), e); - } - - return attributeMap; + return attributeMap; + }); } @Override public TelemetryMap getDeviceTelemetry(String deviceId) { - TelemetryMap telemetryMap = new TelemetryMap(); + return telemetryCache.get(deviceId, id -> { + TelemetryMap telemetryMap = new TelemetryMap(); - try { - DeviceId id = new DeviceId(UUID.fromString(deviceId)); + try { + DeviceId deviceIdObj = new DeviceId(UUID.fromString(id)); - // 获取所有遥测键 - List timeseriesKeys = client.getTimeseriesKeys(id); - if (timeseriesKeys == null || timeseriesKeys.isEmpty()) { - log.debug("设备 {} 没有遥测数据", deviceId); - return telemetryMap; + List timeseriesKeys = client.getTimeseriesKeys(deviceIdObj); + if (timeseriesKeys == null || timeseriesKeys.isEmpty()) { + log.debug("设备 {} 没有遥测数据", id); + return telemetryMap; + } + + List latestTimeseries = client.getLatestTimeseries(deviceIdObj, timeseriesKeys); + if (latestTimeseries == null || latestTimeseries.isEmpty()) { + log.debug("设备 {} 的遥测数据为空", id); + return telemetryMap; + } + + for (TsKvEntry entry : latestTimeseries) { + parseAndPutTelemetry(telemetryMap, entry); + } + + } catch (Exception e) { + log.error("获取设备遥测数据失败: deviceId={}, error={}", id, e.getMessage(), e); } - // 获取最新的遥测数据 - List latestTimeseries = client.getLatestTimeseries(id, timeseriesKeys); - if (latestTimeseries == null || latestTimeseries.isEmpty()) { - log.debug("设备 {} 的遥测数据为空", deviceId); - return telemetryMap; - } - - // 解析并填充到TelemetryMap - for (TsKvEntry entry : latestTimeseries) { - parseAndPutTelemetry(telemetryMap, entry); - } - - } catch (Exception e) { - log.error("获取设备遥测数据失败: deviceId={}, error={}", deviceId, e.getMessage(), e); - } - - return telemetryMap; + return telemetryMap; + }); }