You've already forked FrameTour-BE
refactor(device): 重构设备信息获取逻辑,增加缓存降级策略
- 新增 DeviceV2DTO 转换为 DeviceEntity 的方法 - 引入成功结果缓存,用于失败时降级 - 优化 getDevice 和 getDeviceByDeviceNo 方法,增加异常处理和缓存逻辑 - 清理缓存时增加成功结果缓存的清理
This commit is contained in:
@@ -5,52 +5,107 @@ import com.ycwl.basic.mapper.DeviceMapper;
|
||||
import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity;
|
||||
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
|
||||
import com.ycwl.basic.utils.SnowFlakeUtil;
|
||||
import com.ycwl.basic.integration.device.service.DeviceIntegrationService;
|
||||
import com.ycwl.basic.integration.device.dto.device.DeviceV2DTO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class DeviceRepository {
|
||||
@Autowired
|
||||
private DeviceMapper deviceMapper;
|
||||
@Autowired
|
||||
private RedisTemplate<String, String> redisTemplate;
|
||||
@Autowired
|
||||
private DeviceIntegrationService deviceIntegrationService;
|
||||
|
||||
public static final String DEVICE_ONLINE_CACHE_KEY = "device:online_status:%s";
|
||||
public static final String DEVICE_CACHE_KEY = "device:%s";
|
||||
public static final String DEVICE_CONFIG_CACHE_KEY = "device:%s:config";
|
||||
public static final String DEVICE_CACHE_SUCCESS_KEY = "device:success:%s";
|
||||
public static final String DEVICE_NO_CACHE_SUCCESS_KEY = "device:success:no:%s";
|
||||
|
||||
/**
|
||||
* 将DeviceV2DTO转换为DeviceEntity
|
||||
*/
|
||||
private DeviceEntity convertToEntity(DeviceV2DTO dto) {
|
||||
if (dto == null) {
|
||||
return null;
|
||||
}
|
||||
DeviceEntity entity = new DeviceEntity();
|
||||
entity.setId(dto.getId());
|
||||
entity.setName(dto.getName());
|
||||
entity.setNo(dto.getNo());
|
||||
entity.setScenicId(dto.getScenicId());
|
||||
// DeviceV2DTO中的isActive对应DeviceEntity中的status
|
||||
entity.setStatus(dto.getIsActive());
|
||||
// 转换时间格式:LocalDateTime -> Date
|
||||
if (dto.getCreateTime() != null) {
|
||||
entity.setCreateAt(Date.from(dto.getCreateTime().atZone(ZoneId.systemDefault()).toInstant()));
|
||||
}
|
||||
if (dto.getUpdateTime() != null) {
|
||||
entity.setUpdateAt(Date.from(dto.getUpdateTime().atZone(ZoneId.systemDefault()).toInstant()));
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
public DeviceEntity getDevice(Long deviceId) {
|
||||
if (redisTemplate.hasKey(String.format(DEVICE_CACHE_KEY, deviceId))) {
|
||||
return JacksonUtil.parseObject(redisTemplate.opsForValue().get(String.format(DEVICE_CACHE_KEY, deviceId)), DeviceEntity.class);
|
||||
}
|
||||
DeviceEntity device = deviceMapper.getByDeviceId(deviceId);
|
||||
if (null != device) {
|
||||
log.debug("获取设备信息, deviceId: {}", deviceId);
|
||||
try {
|
||||
DeviceV2DTO deviceDto = deviceIntegrationService.getDevice(deviceId);
|
||||
DeviceEntity device = convertToEntity(deviceDto);
|
||||
if (device != null) {
|
||||
// 存储到常规缓存
|
||||
redisTemplate.opsForValue().set(String.format(DEVICE_CACHE_KEY, deviceId), JacksonUtil.toJSONString(device), 3, TimeUnit.DAYS);
|
||||
// 存储到成功结果缓存,用于失败时降级
|
||||
redisTemplate.opsForValue().set(String.format(DEVICE_CACHE_SUCCESS_KEY, deviceId), JacksonUtil.toJSONString(device), 7, TimeUnit.DAYS);
|
||||
}
|
||||
return device;
|
||||
} catch (Exception e) {
|
||||
log.warn("调用zt-device服务失败, deviceId: {}, 尝试返回缓存结果", deviceId, e);
|
||||
String cachedDevice = redisTemplate.opsForValue().get(String.format(DEVICE_CACHE_SUCCESS_KEY, deviceId));
|
||||
if (cachedDevice != null) {
|
||||
log.info("返回缓存的设备信息, deviceId: {}", deviceId);
|
||||
return JacksonUtil.parseObject(cachedDevice, DeviceEntity.class);
|
||||
}
|
||||
log.error("无法获取设备信息且无缓存数据, deviceId: {}", deviceId);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public DeviceEntity getDeviceByDeviceNo(String deviceNo) {
|
||||
if (redisTemplate.hasKey(String.format(DEVICE_CACHE_KEY, deviceNo))) {
|
||||
return JacksonUtil.parseObject(redisTemplate.opsForValue().get(String.format(DEVICE_CACHE_KEY, deviceNo)), DeviceEntity.class);
|
||||
}
|
||||
DeviceEntity device = deviceMapper.getByDeviceNo(deviceNo);
|
||||
if (null == device) {
|
||||
device = deviceMapper.getByDeviceNo2(deviceNo);
|
||||
}
|
||||
if (null != device) {
|
||||
log.debug("根据设备编号获取设备信息, deviceNo: {}", deviceNo);
|
||||
try {
|
||||
DeviceV2DTO deviceDto = deviceIntegrationService.getDeviceByNo(deviceNo);
|
||||
DeviceEntity device = convertToEntity(deviceDto);
|
||||
if (device != null) {
|
||||
// 存储到常规缓存
|
||||
redisTemplate.opsForValue().set(String.format(DEVICE_CACHE_KEY, deviceNo), JacksonUtil.toJSONString(device), 3, TimeUnit.DAYS);
|
||||
redisTemplate.opsForValue().set(String.format(DEVICE_CACHE_KEY, device.getId()), JacksonUtil.toJSONString(device), 3, TimeUnit.DAYS);
|
||||
} else {
|
||||
redisTemplate.opsForValue().set(String.format(DEVICE_CACHE_KEY, deviceNo), "null", 60L, TimeUnit.SECONDS);
|
||||
// 存储到成功结果缓存,用于失败时降级
|
||||
redisTemplate.opsForValue().set(String.format(DEVICE_NO_CACHE_SUCCESS_KEY, deviceNo), JacksonUtil.toJSONString(device), 7, TimeUnit.DAYS);
|
||||
redisTemplate.opsForValue().set(String.format(DEVICE_CACHE_SUCCESS_KEY, device.getId()), JacksonUtil.toJSONString(device), 7, TimeUnit.DAYS);
|
||||
}
|
||||
return device;
|
||||
} catch (Exception e) {
|
||||
log.warn("调用zt-device服务失败, deviceNo: {}, 尝试返回缓存结果", deviceNo, e);
|
||||
String cachedDevice = redisTemplate.opsForValue().get(String.format(DEVICE_NO_CACHE_SUCCESS_KEY, deviceNo));
|
||||
if (cachedDevice != null) {
|
||||
log.info("返回缓存的设备信息, deviceNo: {}", deviceNo);
|
||||
return JacksonUtil.parseObject(cachedDevice, DeviceEntity.class);
|
||||
}
|
||||
log.error("无法获取设备信息且无缓存数据, deviceNo: {}", deviceNo);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public DeviceConfigEntity getDeviceConfig(Long deviceId) {
|
||||
@@ -82,6 +137,8 @@ public class DeviceRepository {
|
||||
}
|
||||
}
|
||||
redisTemplate.delete(String.format(DEVICE_CACHE_KEY, deviceNo));
|
||||
// 清理成功结果缓存
|
||||
redisTemplate.delete(String.format(DEVICE_NO_CACHE_SUCCESS_KEY, deviceNo));
|
||||
return true;
|
||||
}
|
||||
public boolean clearDeviceCache(Long deviceId) {
|
||||
@@ -92,6 +149,8 @@ public class DeviceRepository {
|
||||
}
|
||||
redisTemplate.delete(String.format(DEVICE_CACHE_KEY, deviceId));
|
||||
redisTemplate.delete(String.format(DEVICE_CONFIG_CACHE_KEY, deviceId));
|
||||
// 清理成功结果缓存
|
||||
redisTemplate.delete(String.format(DEVICE_CACHE_SUCCESS_KEY, deviceId));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user