refactor(integration): 重构集成服务的降级机制

-移除各服务自定义的降级服务类,统一降级逻辑
- 新增 IntegrationFallbackService作为通用降级服务
- 更新设备和景区服务的降级处理方式
- 优化降级缓存管理,增加统计信息和批量清理功能
- 调整 API 接口,移除扁平化批量更新等相关方法
This commit is contained in:
2025-09-02 12:24:55 +08:00
parent d35a1facbd
commit 8c8a6baa5e
13 changed files with 757 additions and 260 deletions

View File

@@ -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);
}

View File

@@ -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("设备集成示例运行完成");
}
}

View File

@@ -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, "批量更新设备配置失败");
}
/**
* 获取设备特定配置值
*/

View File

@@ -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));
}
}

View File

@@ -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,