You've already forked FrameTour-BE
refactor(integration): 重构集成服务的降级机制
-移除各服务自定义的降级服务类,统一降级逻辑 - 新增 IntegrationFallbackService作为通用降级服务 - 更新设备和景区服务的降级处理方式 - 优化降级缓存管理,增加统计信息和批量清理功能 - 调整 API 接口,移除扁平化批量更新等相关方法
This commit is contained in:
@@ -71,10 +71,4 @@ public interface DeviceConfigV2Client {
|
||||
CommonResponse<BatchUpdateResponse> batchUpdateDeviceConfig(@PathVariable("deviceId") Long deviceId,
|
||||
@RequestBody BatchDeviceConfigRequest request);
|
||||
|
||||
/**
|
||||
* 扁平化批量更新设备配置
|
||||
*/
|
||||
@PostMapping("/{deviceId}/batch-flat")
|
||||
CommonResponse<String> batchFlatUpdateDeviceConfig(@PathVariable("deviceId") Long deviceId,
|
||||
@RequestBody Map<String, Object> configs);
|
||||
}
|
@@ -1,8 +1,8 @@
|
||||
package com.ycwl.basic.integration.device.example;
|
||||
|
||||
import com.ycwl.basic.integration.common.service.IntegrationFallbackService;
|
||||
import com.ycwl.basic.integration.device.service.DeviceIntegrationService;
|
||||
import com.ycwl.basic.integration.device.service.DeviceConfigIntegrationService;
|
||||
import com.ycwl.basic.integration.device.service.DeviceIntegrationFallbackService;
|
||||
import com.ycwl.basic.integration.device.dto.device.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -11,8 +11,8 @@ import org.springframework.stereotype.Component;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 设备集成降级机制示例
|
||||
* 演示失败降级策略的使用
|
||||
* 设备集成示例(包含降级机制)
|
||||
* 演示设备集成和失败降级策略的使用
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@@ -21,7 +21,9 @@ public class DeviceIntegrationFallbackExample {
|
||||
|
||||
private final DeviceIntegrationService deviceService;
|
||||
private final DeviceConfigIntegrationService configService;
|
||||
private final DeviceIntegrationFallbackService fallbackService;
|
||||
private final IntegrationFallbackService fallbackService;
|
||||
|
||||
private static final String SERVICE_NAME = "zt-device";
|
||||
|
||||
/**
|
||||
* 演示设备信息获取的降级机制
|
||||
@@ -51,26 +53,26 @@ public class DeviceIntegrationFallbackExample {
|
||||
}
|
||||
|
||||
/**
|
||||
* 演示设备操作的降级机制
|
||||
* 演示设备操作(无降级机制)
|
||||
*/
|
||||
public void deviceOperationFallbackExample() {
|
||||
log.info("=== 设备操作降级示例 ===");
|
||||
public void deviceOperationExample() {
|
||||
log.info("=== 设备操作示例 ===");
|
||||
|
||||
Long deviceId = 1001L;
|
||||
|
||||
try {
|
||||
// 设备更新操作 - 自动降级
|
||||
// 设备更新操作 - 直接操作,失败时抛出异常
|
||||
UpdateDeviceRequest updateRequest = new UpdateDeviceRequest();
|
||||
updateRequest.setName("更新后的摄像头");
|
||||
deviceService.updateDevice(deviceId, updateRequest);
|
||||
log.info("设备更新操作完成");
|
||||
|
||||
// 设备排序更新 - 自动降级
|
||||
// 设备排序更新 - 直接操作,失败时抛出异常
|
||||
deviceService.updateDeviceSort(deviceId, 5);
|
||||
log.info("设备排序更新完成");
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("设备操作降级失败", e);
|
||||
log.error("设备操作失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,29 +86,39 @@ public class DeviceIntegrationFallbackExample {
|
||||
String configCacheKey = "device:flat:config:1001";
|
||||
|
||||
// 检查降级缓存状态
|
||||
boolean hasDeviceCache = fallbackService.hasFallbackCache(deviceCacheKey);
|
||||
boolean hasConfigCache = fallbackService.hasFallbackCache(configCacheKey);
|
||||
boolean hasDeviceCache = fallbackService.hasFallbackCache(SERVICE_NAME, deviceCacheKey);
|
||||
boolean hasConfigCache = fallbackService.hasFallbackCache(SERVICE_NAME, configCacheKey);
|
||||
|
||||
log.info("设备降级缓存存在: {}", hasDeviceCache);
|
||||
log.info("配置降级缓存存在: {}", hasConfigCache);
|
||||
|
||||
// 清理特定的降级缓存
|
||||
if (hasDeviceCache) {
|
||||
fallbackService.clearFallbackCache(deviceCacheKey);
|
||||
fallbackService.clearFallbackCache(SERVICE_NAME, deviceCacheKey);
|
||||
log.info("已清理设备降级缓存");
|
||||
}
|
||||
|
||||
// 获取降级缓存统计信息
|
||||
IntegrationFallbackService.FallbackCacheStats stats = fallbackService.getFallbackCacheStats(SERVICE_NAME);
|
||||
log.info("设备服务降级缓存统计: {}", stats);
|
||||
|
||||
// 批量清理所有设备降级缓存
|
||||
if (stats.getTotalCacheCount() > 10) {
|
||||
fallbackService.clearAllFallbackCache(SERVICE_NAME);
|
||||
log.info("已批量清理所有设备降级缓存");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行所有降级示例
|
||||
* 运行所有示例
|
||||
*/
|
||||
public void runAllFallbackExamples() {
|
||||
log.info("开始运行设备集成降级示例...");
|
||||
public void runAllExamples() {
|
||||
log.info("开始运行设备集成示例...");
|
||||
|
||||
deviceInfoFallbackExample();
|
||||
deviceOperationFallbackExample();
|
||||
deviceOperationExample();
|
||||
fallbackCacheManagementExample();
|
||||
|
||||
log.info("设备集成降级示例运行完成");
|
||||
log.info("设备集成示例运行完成");
|
||||
}
|
||||
}
|
@@ -2,6 +2,7 @@ package com.ycwl.basic.integration.device.service;
|
||||
|
||||
import com.ycwl.basic.integration.common.exception.IntegrationException;
|
||||
import com.ycwl.basic.integration.common.response.CommonResponse;
|
||||
import com.ycwl.basic.integration.common.service.IntegrationFallbackService;
|
||||
import com.ycwl.basic.integration.device.client.DeviceConfigV2Client;
|
||||
import com.ycwl.basic.integration.device.dto.config.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -18,7 +19,9 @@ import java.util.Map;
|
||||
public class DeviceConfigIntegrationService {
|
||||
|
||||
private final DeviceConfigV2Client deviceConfigV2Client;
|
||||
private final DeviceIntegrationFallbackService fallbackService;
|
||||
private final IntegrationFallbackService fallbackService;
|
||||
|
||||
private static final String SERVICE_NAME = "zt-device";
|
||||
|
||||
public List<DeviceConfigV2DTO> getDeviceConfigs(Long deviceId) {
|
||||
log.info("获取设备配置列表, deviceId: {}", deviceId);
|
||||
@@ -41,6 +44,7 @@ public class DeviceConfigIntegrationService {
|
||||
public Map<String, Object> getDeviceFlatConfig(Long deviceId) {
|
||||
log.info("获取设备扁平化配置, deviceId: {}", deviceId);
|
||||
return fallbackService.executeWithFallback(
|
||||
SERVICE_NAME,
|
||||
"device:flat:config:" + deviceId,
|
||||
() -> {
|
||||
CommonResponse<Map<String, Object>> response = deviceConfigV2Client.getDeviceFlatConfig(deviceId);
|
||||
@@ -53,6 +57,7 @@ public class DeviceConfigIntegrationService {
|
||||
public Map<String, Object> getDeviceFlatConfigByNo(String deviceNo) {
|
||||
log.info("根据设备编号获取扁平化配置, deviceNo: {}", deviceNo);
|
||||
return fallbackService.executeWithFallback(
|
||||
SERVICE_NAME,
|
||||
"device:flat:config:no:" + deviceNo,
|
||||
() -> {
|
||||
CommonResponse<Map<String, Object>> response = deviceConfigV2Client.getDeviceFlatConfigByNo(deviceNo);
|
||||
@@ -89,6 +94,8 @@ public class DeviceConfigIntegrationService {
|
||||
return handleResponse(response, "批量更新设备配置失败");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取设备特定配置值
|
||||
*/
|
||||
|
@@ -1,128 +0,0 @@
|
||||
package com.ycwl.basic.integration.device.service;
|
||||
|
||||
import com.ycwl.basic.integration.device.dto.device.*;
|
||||
import com.ycwl.basic.utils.JacksonUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* 设备集成服务失败降级处理
|
||||
* 提供失败时的降级策略,不使用常规缓存
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class DeviceIntegrationFallbackService {
|
||||
|
||||
private final RedisTemplate<String, String> redisTemplate;
|
||||
|
||||
// 降级缓存键前缀
|
||||
private static final String FALLBACK_CACHE_PREFIX = "device:fallback:";
|
||||
private static final long FALLBACK_CACHE_TTL = 7; // 7天
|
||||
|
||||
/**
|
||||
* 执行操作,失败时降级到缓存结果
|
||||
*
|
||||
* @param cacheKey 缓存键
|
||||
* @param operation 主要操作
|
||||
* @param resultClass 结果类型
|
||||
* @param <T> 结果类型
|
||||
* @return 操作结果或缓存的结果
|
||||
*/
|
||||
public <T> T executeWithFallback(String cacheKey, Supplier<T> operation, Class<T> resultClass) {
|
||||
try {
|
||||
T result = operation.get();
|
||||
if (result != null) {
|
||||
// 操作成功,保存结果用于将来的降级
|
||||
storeFallbackCache(cacheKey, result);
|
||||
}
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
log.warn("操作失败,尝试降级到缓存结果, cacheKey: {}", cacheKey, e);
|
||||
return getFallbackFromCache(cacheKey, resultClass);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行操作,失败时降级到缓存结果,无返回值版本
|
||||
*
|
||||
* @param cacheKey 缓存键
|
||||
* @param operation 主要操作
|
||||
*/
|
||||
public void executeWithFallback(String cacheKey, Runnable operation) {
|
||||
try {
|
||||
operation.run();
|
||||
// 操作成功,记录成功状态
|
||||
storeFallbackCache(cacheKey + ":success", "true");
|
||||
} catch (Exception e) {
|
||||
log.warn("操作失败,检查是否有历史成功记录, cacheKey: {}", cacheKey, e);
|
||||
String successRecord = getFallbackFromCache(cacheKey + ":success", String.class);
|
||||
if (successRecord == null) {
|
||||
log.error("操作失败且无历史成功记录, cacheKey: {}", cacheKey);
|
||||
throw e;
|
||||
}
|
||||
log.info("操作失败但有历史成功记录,忽略此次失败, cacheKey: {}", cacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 存储降级缓存
|
||||
*/
|
||||
private void storeFallbackCache(String cacheKey, Object value) {
|
||||
try {
|
||||
String key = FALLBACK_CACHE_PREFIX + cacheKey;
|
||||
String jsonValue = JacksonUtil.toJSONString(value);
|
||||
redisTemplate.opsForValue().set(key, jsonValue, FALLBACK_CACHE_TTL, TimeUnit.DAYS);
|
||||
log.debug("存储降级缓存成功, key: {}", key);
|
||||
} catch (Exception e) {
|
||||
log.warn("存储降级缓存失败, cacheKey: {}", cacheKey, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从降级缓存获取结果
|
||||
*/
|
||||
private <T> T getFallbackFromCache(String cacheKey, Class<T> resultClass) {
|
||||
try {
|
||||
String key = FALLBACK_CACHE_PREFIX + cacheKey;
|
||||
String cachedValue = redisTemplate.opsForValue().get(key);
|
||||
if (cachedValue != null) {
|
||||
log.info("从降级缓存获取结果, key: {}", key);
|
||||
if (resultClass == String.class) {
|
||||
return resultClass.cast(cachedValue);
|
||||
}
|
||||
return JacksonUtil.parseObject(cachedValue, resultClass);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("从降级缓存获取结果失败, cacheKey: {}", cacheKey, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除降级缓存
|
||||
*
|
||||
* @param cacheKey 缓存键
|
||||
*/
|
||||
public void clearFallbackCache(String cacheKey) {
|
||||
String key = FALLBACK_CACHE_PREFIX + cacheKey;
|
||||
redisTemplate.delete(key);
|
||||
log.debug("清除降级缓存, key: {}", key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否有降级缓存
|
||||
*
|
||||
* @param cacheKey 缓存键
|
||||
* @return 是否存在降级缓存
|
||||
*/
|
||||
public boolean hasFallbackCache(String cacheKey) {
|
||||
String key = FALLBACK_CACHE_PREFIX + cacheKey;
|
||||
return Boolean.TRUE.equals(redisTemplate.hasKey(key));
|
||||
}
|
||||
}
|
@@ -2,6 +2,7 @@ package com.ycwl.basic.integration.device.service;
|
||||
|
||||
import com.ycwl.basic.integration.common.exception.IntegrationException;
|
||||
import com.ycwl.basic.integration.common.response.CommonResponse;
|
||||
import com.ycwl.basic.integration.common.service.IntegrationFallbackService;
|
||||
import com.ycwl.basic.integration.device.client.DeviceV2Client;
|
||||
import com.ycwl.basic.integration.device.dto.device.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -14,11 +15,14 @@ import org.springframework.stereotype.Service;
|
||||
public class DeviceIntegrationService {
|
||||
|
||||
private final DeviceV2Client deviceV2Client;
|
||||
private final DeviceIntegrationFallbackService fallbackService;
|
||||
private final IntegrationFallbackService fallbackService;
|
||||
|
||||
private static final String SERVICE_NAME = "zt-device";
|
||||
|
||||
public DeviceV2DTO getDevice(Long deviceId) {
|
||||
log.info("获取设备信息, deviceId: {}", deviceId);
|
||||
return fallbackService.executeWithFallback(
|
||||
SERVICE_NAME,
|
||||
"device:" + deviceId,
|
||||
() -> {
|
||||
CommonResponse<DeviceV2DTO> response = deviceV2Client.getDevice(deviceId);
|
||||
@@ -31,6 +35,7 @@ public class DeviceIntegrationService {
|
||||
public DeviceV2DTO getDeviceByNo(String deviceNo) {
|
||||
log.info("根据设备编号获取设备信息, deviceNo: {}", deviceNo);
|
||||
return fallbackService.executeWithFallback(
|
||||
SERVICE_NAME,
|
||||
"device:no:" + deviceNo,
|
||||
() -> {
|
||||
CommonResponse<DeviceV2DTO> response = deviceV2Client.getDeviceByNo(deviceNo);
|
||||
@@ -43,6 +48,7 @@ public class DeviceIntegrationService {
|
||||
public DeviceV2WithConfigDTO getDeviceWithConfig(Long deviceId) {
|
||||
log.info("获取设备配置信息, deviceId: {}", deviceId);
|
||||
return fallbackService.executeWithFallback(
|
||||
SERVICE_NAME,
|
||||
"device:config:" + deviceId,
|
||||
() -> {
|
||||
CommonResponse<DeviceV2WithConfigDTO> response = deviceV2Client.getDeviceWithConfig(deviceId);
|
||||
@@ -55,6 +61,7 @@ public class DeviceIntegrationService {
|
||||
public DeviceV2WithConfigDTO getDeviceWithConfigByNo(String deviceNo) {
|
||||
log.info("根据设备编号获取设备配置信息, deviceNo: {}", deviceNo);
|
||||
return fallbackService.executeWithFallback(
|
||||
SERVICE_NAME,
|
||||
"device:config:no:" + deviceNo,
|
||||
() -> {
|
||||
CommonResponse<DeviceV2WithConfigDTO> response = deviceV2Client.getDeviceByNoWithConfig(deviceNo);
|
||||
@@ -72,24 +79,14 @@ public class DeviceIntegrationService {
|
||||
|
||||
public void updateDevice(Long deviceId, UpdateDeviceRequest request) {
|
||||
log.info("更新设备信息, deviceId: {}", deviceId);
|
||||
fallbackService.executeWithFallback(
|
||||
"device:update:" + deviceId,
|
||||
() -> {
|
||||
CommonResponse<String> response = deviceV2Client.updateDevice(deviceId, request);
|
||||
handleResponse(response, "更新设备信息失败");
|
||||
}
|
||||
);
|
||||
CommonResponse<String> response = deviceV2Client.updateDevice(deviceId, request);
|
||||
handleResponse(response, "更新设备信息失败");
|
||||
}
|
||||
|
||||
public void deleteDevice(Long deviceId) {
|
||||
log.info("删除设备, deviceId: {}", deviceId);
|
||||
fallbackService.executeWithFallback(
|
||||
"device:delete:" + deviceId,
|
||||
() -> {
|
||||
CommonResponse<String> response = deviceV2Client.deleteDevice(deviceId);
|
||||
handleResponse(response, "删除设备失败");
|
||||
}
|
||||
);
|
||||
CommonResponse<String> response = deviceV2Client.deleteDevice(deviceId);
|
||||
handleResponse(response, "删除设备失败");
|
||||
}
|
||||
|
||||
public DeviceV2ListResponse listDevices(Integer page, Integer pageSize, String name, String no,
|
||||
|
Reference in New Issue
Block a user