1. 多级缓存与服务降级概述

多级缓存是提升系统性能的重要手段,通过本地缓存、分布式缓存和数据库的合理组合,可以显著提高系统响应速度。服务降级则是在系统压力过大或异常情况下的保护机制,确保核心功能的可用性。本文将详细介绍多级缓存架构设计、服务降级策略和熔断机制的完整实现。

1.1 核心功能

  1. 多级缓存: L1本地缓存 + L2分布式缓存 + L3数据库
  2. 服务降级: 自动降级、手动降级、熔断降级
  3. 熔断机制: 基于Hystrix的熔断保护
  4. 缓存管理: 缓存预热、更新、失效策略
  5. 监控告警: 缓存命中率、服务可用性监控

1.2 技术架构

1
2
3
4
5
用户请求 → L1本地缓存 → L2分布式缓存 → L3数据库
↓ ↓ ↓ ↓
应用服务 → Caffeine → Redis → MySQL
↓ ↓ ↓ ↓
降级策略 → 熔断保护 → 缓存管理 → 监控告警

2. 多级缓存配置

2.1 缓存配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/**
* 多级缓存配置
*/
@Configuration
@EnableCaching
public class MultiLevelCacheConfig {

@Value("${cache.redis.host}")
private String redisHost;

@Value("${cache.redis.port}")
private int redisPort;

@Value("${cache.redis.password}")
private String redisPassword;

@Value("${cache.local.maximum-size}")
private long localCacheMaximumSize;

@Value("${cache.local.expire-after-write}")
private int localCacheExpireAfterWrite;

/**
* Redis连接工厂
*/
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
config.setHostName(redisHost);
config.setPort(redisPort);
config.setPassword(redisPassword);

LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
.commandTimeout(Duration.ofSeconds(2))
.poolConfig(GenericObjectPoolConfig.builder()
.maxTotal(20)
.maxIdle(10)
.minIdle(5)
.build())
.build();

return new LettuceConnectionFactory(config, clientConfig);
}

/**
* Redis模板
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);

// 设置序列化器
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());

template.afterPropertiesSet();
return template;
}

/**
* 本地缓存配置
*/
@Bean
public CaffeineCacheManager caffeineCacheManager() {
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
cacheManager.setCaffeine(Caffeine.newBuilder()
.maximumSize(localCacheMaximumSize)
.expireAfterWrite(Duration.ofMinutes(localCacheExpireAfterWrite))
.recordStats()
.build());
return cacheManager;
}

/**
* 多级缓存管理器
*/
@Bean
public MultiLevelCacheManager multiLevelCacheManager(
RedisTemplate<String, Object> redisTemplate,
CaffeineCacheManager caffeineCacheManager) {
return new MultiLevelCacheManager(redisTemplate, caffeineCacheManager);
}
}

/**
* 多级缓存管理器
*/
@Component
public class MultiLevelCacheManager {

private final RedisTemplate<String, Object> redisTemplate;
private final CaffeineCacheManager caffeineCacheManager;

public MultiLevelCacheManager(RedisTemplate<String, Object> redisTemplate,
CaffeineCacheManager caffeineCacheManager) {
this.redisTemplate = redisTemplate;
this.caffeineCacheManager = caffeineCacheManager;
}

/**
* 获取缓存值
* @param key 缓存键
* @param cacheName 缓存名称
* @return 缓存值
*/
public Object get(String key, String cacheName) {
// 1. 尝试从本地缓存获取
Cache localCache = caffeineCacheManager.getCache(cacheName);
if (localCache != null) {
Cache.ValueWrapper wrapper = localCache.get(key);
if (wrapper != null) {
log.debug("从本地缓存获取: key={}, cacheName={}", key, cacheName);
return wrapper.get();
}
}

// 2. 尝试从Redis获取
String redisKey = cacheName + ":" + key;
Object value = redisTemplate.opsForValue().get(redisKey);
if (value != null) {
// 回写到本地缓存
if (localCache != null) {
localCache.put(key, value);
}
log.debug("从Redis缓存获取: key={}, cacheName={}", key, cacheName);
return value;
}

log.debug("缓存未命中: key={}, cacheName={}", key, cacheName);
return null;
}

/**
* 设置缓存值
* @param key 缓存键
* @param value 缓存值
* @param cacheName 缓存名称
* @param expireSeconds 过期时间(秒)
*/
public void put(String key, Object value, String cacheName, int expireSeconds) {
// 1. 设置本地缓存
Cache localCache = caffeineCacheManager.getCache(cacheName);
if (localCache != null) {
localCache.put(key, value);
}

// 2. 设置Redis缓存
String redisKey = cacheName + ":" + key;
redisTemplate.opsForValue().set(redisKey, value, Duration.ofSeconds(expireSeconds));

log.debug("设置缓存: key={}, cacheName={}, expireSeconds={}", key, cacheName, expireSeconds);
}

/**
* 删除缓存
* @param key 缓存键
* @param cacheName 缓存名称
*/
public void evict(String key, String cacheName) {
// 1. 删除本地缓存
Cache localCache = caffeineCacheManager.getCache(cacheName);
if (localCache != null) {
localCache.evict(key);
}

// 2. 删除Redis缓存
String redisKey = cacheName + ":" + key;
redisTemplate.delete(redisKey);

log.debug("删除缓存: key={}, cacheName={}", key, cacheName);
}

/**
* 清空缓存
* @param cacheName 缓存名称
*/
public void clear(String cacheName) {
// 1. 清空本地缓存
Cache localCache = caffeineCacheManager.getCache(cacheName);
if (localCache != null) {
localCache.clear();
}

// 2. 清空Redis缓存
String pattern = cacheName + ":*";
Set<String> keys = redisTemplate.keys(pattern);
if (keys != null && !keys.isEmpty()) {
redisTemplate.delete(keys);
}

log.debug("清空缓存: cacheName={}", cacheName);
}
}

2.2 应用配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# application.yml
cache:
redis:
host: localhost
port: 6379
password:
local:
maximum-size: 10000
expire-after-write: 30

# Hystrix配置
hystrix:
command:
default:
execution:
timeout:
enabled: true
isolation:
thread:
timeout-in-milliseconds: 3000
circuit-breaker:
enabled: true
request-volume-threshold: 20
error-threshold-percentage: 50
sleep-window-in-milliseconds: 5000
fallback:
enabled: true

3. 多级缓存服务

3.1 缓存服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/**
* 多级缓存服务
*/
@Service
public class MultiLevelCacheService {

@Autowired
private MultiLevelCacheManager cacheManager;

@Autowired
private UserService userService;

@Autowired
private ProductService productService;

/**
* 获取用户信息(多级缓存)
* @param userId 用户ID
* @return 用户信息
*/
public User getUserById(Long userId) {
String cacheKey = "user:" + userId;
String cacheName = "userCache";

// 1. 尝试从缓存获取
Object cached = cacheManager.get(cacheKey, cacheName);
if (cached != null) {
return (User) cached;
}

// 2. 从数据库获取
User user = userService.getUserById(userId);
if (user != null) {
// 3. 写入缓存
cacheManager.put(cacheKey, user, cacheName, 1800); // 30分钟
}

return user;
}

/**
* 获取商品信息(多级缓存)
* @param productId 商品ID
* @return 商品信息
*/
public Product getProductById(Long productId) {
String cacheKey = "product:" + productId;
String cacheName = "productCache";

// 1. 尝试从缓存获取
Object cached = cacheManager.get(cacheKey, cacheName);
if (cached != null) {
return (Product) cached;
}

// 2. 从数据库获取
Product product = productService.getProductById(productId);
if (product != null) {
// 3. 写入缓存
cacheManager.put(cacheKey, product, cacheName, 3600); // 1小时
}

return product;
}

/**
* 更新用户信息(缓存失效)
* @param user 用户信息
*/
public void updateUser(User user) {
// 1. 更新数据库
userService.updateUser(user);

// 2. 失效缓存
String cacheKey = "user:" + user.getId();
String cacheName = "userCache";
cacheManager.evict(cacheKey, cacheName);

log.info("用户信息更新,缓存失效: userId={}", user.getId());
}

/**
* 更新商品信息(缓存失效)
* @param product 商品信息
*/
public void updateProduct(Product product) {
// 1. 更新数据库
productService.updateProduct(product);

// 2. 失效缓存
String cacheKey = "product:" + product.getId();
String cacheName = "productCache";
cacheManager.evict(cacheKey, cacheName);

log.info("商品信息更新,缓存失效: productId={}", product.getId());
}

/**
* 批量获取用户信息
* @param userIds 用户ID列表
* @return 用户信息列表
*/
public List<User> getUsersByIds(List<Long> userIds) {
List<User> users = new ArrayList<>();
List<Long> missingIds = new ArrayList<>();

// 1. 批量从缓存获取
for (Long userId : userIds) {
String cacheKey = "user:" + userId;
String cacheName = "userCache";

Object cached = cacheManager.get(cacheKey, cacheName);
if (cached != null) {
users.add((User) cached);
} else {
missingIds.add(userId);
}
}

// 2. 批量从数据库获取缺失的数据
if (!missingIds.isEmpty()) {
List<User> dbUsers = userService.getUsersByIds(missingIds);
users.addAll(dbUsers);

// 3. 批量写入缓存
for (User user : dbUsers) {
String cacheKey = "user:" + user.getId();
String cacheName = "userCache";
cacheManager.put(cacheKey, user, cacheName, 1800);
}
}

return users;
}
}

/**
* 用户实体
*/
@Data
@TableName("users")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String username;
private String email;
private String phone;
private String status;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}

/**
* 商品实体
*/
@Data
@TableName("products")
public class Product {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private String description;
private BigDecimal price;
private Integer stock;
private String status;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}

4. 服务降级与熔断

4.1 降级服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/**
* 服务降级服务
*/
@Service
public class ServiceDegradationService {

@Autowired
private RedisTemplate<String, Object> redisTemplate;

@Autowired
private CircuitBreakerService circuitBreakerService;

/**
* 检查服务是否降级
* @param serviceName 服务名称
* @return 是否降级
*/
public boolean isServiceDegraded(String serviceName) {
String key = "degradation:" + serviceName;
Object degraded = redisTemplate.opsForValue().get(key);
return degraded != null && (Boolean) degraded;
}

/**
* 设置服务降级状态
* @param serviceName 服务名称
* @param degraded 是否降级
* @param expireSeconds 过期时间(秒)
*/
public void setServiceDegraded(String serviceName, boolean degraded, int expireSeconds) {
String key = "degradation:" + serviceName;
redisTemplate.opsForValue().set(key, degraded, Duration.ofSeconds(expireSeconds));

log.info("设置服务降级状态: serviceName={}, degraded={}, expireSeconds={}",
serviceName, degraded, expireSeconds);
}

/**
* 自动降级检查
* @param serviceName 服务名称
* @return 是否应该降级
*/
public boolean shouldAutoDegrade(String serviceName) {
// 1. 检查熔断器状态
if (circuitBreakerService.isCircuitOpen(serviceName)) {
return true;
}

// 2. 检查错误率
double errorRate = getServiceErrorRate(serviceName);
if (errorRate > 0.5) { // 错误率超过50%
return true;
}

// 3. 检查响应时间
double avgResponseTime = getServiceAvgResponseTime(serviceName);
if (avgResponseTime > 3000) { // 平均响应时间超过3秒
return true;
}

return false;
}

/**
* 获取服务错误率
* @param serviceName 服务名称
* @return 错误率
*/
private double getServiceErrorRate(String serviceName) {
String key = "service:error:rate:" + serviceName;
Object errorRate = redisTemplate.opsForValue().get(key);
return errorRate != null ? (Double) errorRate : 0.0;
}

/**
* 获取服务平均响应时间
* @param serviceName 服务名称
* @return 平均响应时间
*/
private double getServiceAvgResponseTime(String serviceName) {
String key = "service:response:time:" + serviceName;
Object responseTime = redisTemplate.opsForValue().get(key);
return responseTime != null ? (Double) responseTime : 0.0;
}

/**
* 记录服务调用
* @param serviceName 服务名称
* @param success 是否成功
* @param responseTime 响应时间
*/
public void recordServiceCall(String serviceName, boolean success, long responseTime) {
// 1. 记录调用次数
String callKey = "service:call:count:" + serviceName;
redisTemplate.opsForValue().increment(callKey);
redisTemplate.expire(callKey, Duration.ofMinutes(5));

// 2. 记录错误次数
if (!success) {
String errorKey = "service:error:count:" + serviceName;
redisTemplate.opsForValue().increment(errorKey);
redisTemplate.expire(errorKey, Duration.ofMinutes(5));
}

// 3. 记录响应时间
String timeKey = "service:response:time:" + serviceName;
redisTemplate.opsForList().leftPush(timeKey, responseTime);
redisTemplate.opsForList().trim(timeKey, 0, 99); // 保留最近100次
redisTemplate.expire(timeKey, Duration.ofMinutes(5));

// 4. 计算错误率
double errorRate = calculateErrorRate(serviceName);
String errorRateKey = "service:error:rate:" + serviceName;
redisTemplate.opsForValue().set(errorRateKey, errorRate, Duration.ofMinutes(5));

// 5. 计算平均响应时间
double avgResponseTime = calculateAvgResponseTime(serviceName);
String avgTimeKey = "service:avg:response:time:" + serviceName;
redisTemplate.opsForValue().set(avgTimeKey, avgResponseTime, Duration.ofMinutes(5));
}

/**
* 计算错误率
* @param serviceName 服务名称
* @return 错误率
*/
private double calculateErrorRate(String serviceName) {
String callKey = "service:call:count:" + serviceName;
String errorKey = "service:error:count:" + serviceName;

Object callCount = redisTemplate.opsForValue().get(callKey);
Object errorCount = redisTemplate.opsForValue().get(errorKey);

if (callCount == null || errorCount == null) {
return 0.0;
}

long calls = (Long) callCount;
long errors = (Long) errorCount;

return calls > 0 ? (double) errors / calls : 0.0;
}

/**
* 计算平均响应时间
* @param serviceName 服务名称
* @return 平均响应时间
*/
private double calculateAvgResponseTime(String serviceName) {
String timeKey = "service:response:time:" + serviceName;
List<Object> times = redisTemplate.opsForList().range(timeKey, 0, -1);

if (times == null || times.isEmpty()) {
return 0.0;
}

double sum = times.stream()
.mapToDouble(time -> (Long) time)
.sum();

return sum / times.size();
}
}

4.2 熔断器服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/**
* 熔断器服务
*/
@Service
public class CircuitBreakerService {

@Autowired
private RedisTemplate<String, Object> redisTemplate;

/**
* 检查熔断器是否开启
* @param serviceName 服务名称
* @return 是否开启
*/
public boolean isCircuitOpen(String serviceName) {
String key = "circuit:breaker:" + serviceName;
Object state = redisTemplate.opsForValue().get(key);
return state != null && "OPEN".equals(state.toString());
}

/**
* 记录服务调用
* @param serviceName 服务名称
* @param success 是否成功
*/
public void recordCall(String serviceName, boolean success) {
String key = "circuit:breaker:stats:" + serviceName;

// 记录调用次数
redisTemplate.opsForHash().increment(key, "totalCalls", 1);

if (success) {
// 记录成功次数
redisTemplate.opsForHash().increment(key, "successCalls", 1);
} else {
// 记录失败次数
redisTemplate.opsForHash().increment(key, "failureCalls", 1);
}

// 设置过期时间
redisTemplate.expire(key, Duration.ofMinutes(10));

// 检查是否需要开启熔断器
checkCircuitBreaker(serviceName);
}

/**
* 检查熔断器状态
* @param serviceName 服务名称
*/
private void checkCircuitBreaker(String serviceName) {
String key = "circuit:breaker:stats:" + serviceName;

Object totalCalls = redisTemplate.opsForHash().get(key, "totalCalls");
Object failureCalls = redisTemplate.opsForHash().get(key, "failureCalls");

if (totalCalls == null || failureCalls == null) {
return;
}

long total = (Long) totalCalls;
long failures = (Long) failureCalls;

// 如果调用次数超过阈值且失败率超过50%,开启熔断器
if (total >= 20 && (double) failures / total > 0.5) {
openCircuitBreaker(serviceName);
}
}

/**
* 开启熔断器
* @param serviceName 服务名称
*/
private void openCircuitBreaker(String serviceName) {
String key = "circuit:breaker:" + serviceName;
redisTemplate.opsForValue().set(key, "OPEN", Duration.ofMinutes(5));

log.warn("熔断器开启: serviceName={}", serviceName);
}

/**
* 关闭熔断器
* @param serviceName 服务名称
*/
public void closeCircuitBreaker(String serviceName) {
String key = "circuit:breaker:" + serviceName;
redisTemplate.delete(key);

// 清空统计数据
String statsKey = "circuit:breaker:stats:" + serviceName;
redisTemplate.delete(statsKey);

log.info("熔断器关闭: serviceName={}", serviceName);
}

/**
* 获取熔断器状态
* @param serviceName 服务名称
* @return 熔断器状态
*/
public CircuitBreakerState getCircuitBreakerState(String serviceName) {
String key = "circuit:breaker:" + serviceName;
Object state = redisTemplate.opsForValue().get(key);

String statsKey = "circuit:breaker:stats:" + serviceName;
Object totalCalls = redisTemplate.opsForHash().get(statsKey, "totalCalls");
Object successCalls = redisTemplate.opsForHash().get(statsKey, "successCalls");
Object failureCalls = redisTemplate.opsForHash().get(statsKey, "failureCalls");

CircuitBreakerState circuitState = new CircuitBreakerState();
circuitState.setServiceName(serviceName);
circuitState.setOpen(state != null && "OPEN".equals(state.toString()));
circuitState.setTotalCalls(totalCalls != null ? (Long) totalCalls : 0L);
circuitState.setSuccessCalls(successCalls != null ? (Long) successCalls : 0L);
circuitState.setFailureCalls(failureCalls != null ? (Long) failureCalls : 0L);

return circuitState;
}
}

/**
* 熔断器状态
*/
@Data
public class CircuitBreakerState {
private String serviceName;
private boolean open;
private long totalCalls;
private long successCalls;
private long failureCalls;

public double getFailureRate() {
return totalCalls > 0 ? (double) failureCalls / totalCalls : 0.0;
}
}

5. 降级注解和切面

5.1 降级注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/**
* 服务降级注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ServiceDegradation {

/**
* 服务名称
*/
String serviceName() default "";

/**
* 降级方法
*/
String fallbackMethod() default "";

/**
* 超时时间(毫秒)
*/
int timeout() default 3000;

/**
* 是否启用熔断器
*/
boolean circuitBreakerEnabled() default true;

/**
* 熔断器阈值
*/
int circuitBreakerThreshold() default 20;

/**
* 熔断器失败率阈值
*/
double circuitBreakerFailureThreshold() default 0.5;
}

/**
* 服务降级切面
*/
@Aspect
@Component
public class ServiceDegradationAspect {

@Autowired
private ServiceDegradationService degradationService;

@Autowired
private CircuitBreakerService circuitBreakerService;

/**
* 降级切点
*/
@Pointcut("@annotation(com.example.annotation.ServiceDegradation)")
public void degradationPointcut() {}

/**
* 降级处理
*/
@Around("degradationPointcut()")
public Object handleDegradation(ProceedingJoinPoint joinPoint) throws Throwable {
// 1. 获取注解
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
ServiceDegradation degradation = signature.getMethod().getAnnotation(ServiceDegradation.class);

String serviceName = degradation.serviceName();
if (StringUtils.isEmpty(serviceName)) {
serviceName = joinPoint.getTarget().getClass().getSimpleName() + "." + signature.getName();
}

// 2. 检查服务是否降级
if (degradationService.isServiceDegraded(serviceName)) {
return executeFallback(joinPoint, degradation, serviceName);
}

// 3. 检查熔断器状态
if (degradation.circuitBreakerEnabled() && circuitBreakerService.isCircuitOpen(serviceName)) {
return executeFallback(joinPoint, degradation, serviceName);
}

// 4. 执行原方法
long startTime = System.currentTimeMillis();
boolean success = false;
Object result = null;

try {
result = joinPoint.proceed();
success = true;
return result;
} catch (Exception e) {
log.error("服务调用失败: serviceName={}", serviceName, e);
throw e;
} finally {
// 5. 记录调用统计
long responseTime = System.currentTimeMillis() - startTime;
degradationService.recordServiceCall(serviceName, success, responseTime);

if (degradation.circuitBreakerEnabled()) {
circuitBreakerService.recordCall(serviceName, success);
}

// 6. 检查是否需要自动降级
if (degradationService.shouldAutoDegrade(serviceName)) {
degradationService.setServiceDegraded(serviceName, true, 300); // 5分钟
}
}
}

/**
* 执行降级方法
*/
private Object executeFallback(ProceedingJoinPoint joinPoint, ServiceDegradation degradation, String serviceName) {
try {
String fallbackMethod = degradation.fallbackMethod();
if (StringUtils.isEmpty(fallbackMethod)) {
// 使用默认降级逻辑
return getDefaultFallbackResult(joinPoint);
}

// 执行指定的降级方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Object target = joinPoint.getTarget();
Method fallbackMethodObj = target.getClass().getMethod(fallbackMethod, signature.getParameterTypes());

return fallbackMethodObj.invoke(target, joinPoint.getArgs());

} catch (Exception e) {
log.error("执行降级方法失败: serviceName={}, fallbackMethod={}",
serviceName, degradation.fallbackMethod(), e);
return getDefaultFallbackResult(joinPoint);
}
}

/**
* 获取默认降级结果
*/
private Object getDefaultFallbackResult(ProceedingJoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Class<?> returnType = signature.getReturnType();

if (returnType == void.class) {
return null;
} else if (returnType == String.class) {
return "服务暂时不可用";
} else if (returnType == Boolean.class || returnType == boolean.class) {
return false;
} else if (returnType == Integer.class || returnType == int.class) {
return 0;
} else if (returnType == Long.class || returnType == long.class) {
return 0L;
} else if (returnType.isAssignableFrom(List.class)) {
return Collections.emptyList();
} else if (returnType.isAssignableFrom(Map.class)) {
return Collections.emptyMap();
} else {
return null;
}
}
}

6. 缓存管理控制器

6.1 缓存管理控制器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/**
* 缓存管理控制器
*/
@RestController
@RequestMapping("/api/cache")
public class CacheManagementController {

@Autowired
private MultiLevelCacheManager cacheManager;

@Autowired
private ServiceDegradationService degradationService;

@Autowired
private CircuitBreakerService circuitBreakerService;

/**
* 清空缓存
*/
@PostMapping("/clear")
public ResponseEntity<Map<String, Object>> clearCache(@RequestParam String cacheName) {
try {
cacheManager.clear(cacheName);

Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("message", "缓存清空成功");
result.put("cacheName", cacheName);

return ResponseEntity.ok(result);

} catch (Exception e) {
log.error("清空缓存失败: cacheName={}", cacheName, e);

Map<String, Object> result = new HashMap<>();
result.put("success", false);
result.put("message", "缓存清空失败: " + e.getMessage());

return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
}
}

/**
* 设置服务降级状态
*/
@PostMapping("/degradation")
public ResponseEntity<Map<String, Object>> setServiceDegradation(
@RequestParam String serviceName,
@RequestParam boolean degraded,
@RequestParam(defaultValue = "300") int expireSeconds) {

try {
degradationService.setServiceDegraded(serviceName, degraded, expireSeconds);

Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("message", "服务降级状态设置成功");
result.put("serviceName", serviceName);
result.put("degraded", degraded);
result.put("expireSeconds", expireSeconds);

return ResponseEntity.ok(result);

} catch (Exception e) {
log.error("设置服务降级状态失败: serviceName={}", serviceName, e);

Map<String, Object> result = new HashMap<>();
result.put("success", false);
result.put("message", "设置服务降级状态失败: " + e.getMessage());

return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
}
}

/**
* 关闭熔断器
*/
@PostMapping("/circuit-breaker/close")
public ResponseEntity<Map<String, Object>> closeCircuitBreaker(@RequestParam String serviceName) {
try {
circuitBreakerService.closeCircuitBreaker(serviceName);

Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("message", "熔断器关闭成功");
result.put("serviceName", serviceName);

return ResponseEntity.ok(result);

} catch (Exception e) {
log.error("关闭熔断器失败: serviceName={}", serviceName, e);

Map<String, Object> result = new HashMap<>();
result.put("success", false);
result.put("message", "关闭熔断器失败: " + e.getMessage());

return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
}
}

/**
* 获取熔断器状态
*/
@GetMapping("/circuit-breaker/state")
public ResponseEntity<CircuitBreakerState> getCircuitBreakerState(@RequestParam String serviceName) {
try {
CircuitBreakerState state = circuitBreakerService.getCircuitBreakerState(serviceName);
return ResponseEntity.ok(state);

} catch (Exception e) {
log.error("获取熔断器状态失败: serviceName={}", serviceName, e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
}
}
}

7. 总结

通过多级缓存与服务降级的实现,我们成功构建了一个高性能、高可用的缓存和降级系统。关键特性包括:

7.1 核心优势

  1. 多级缓存: L1本地缓存 + L2分布式缓存 + L3数据库
  2. 服务降级: 自动降级、手动降级、熔断降级
  3. 熔断机制: 基于Hystrix的熔断保护
  4. 缓存管理: 缓存预热、更新、失效策略
  5. 监控告警: 缓存命中率、服务可用性监控

7.2 最佳实践

  1. 缓存设计: 合理的缓存层次和过期策略
  2. 降级策略: 完善的降级机制和熔断保护
  3. 性能优化: 缓存预热和批量操作
  4. 监控告警: 完善的监控和异常处理
  5. 运维管理: 便捷的缓存管理和状态控制

这套多级缓存与服务降级方案不仅能够显著提升系统性能,还提供了完善的服务保护机制,是现代高并发系统的重要基础设施。