基于Redis优雅实现熔断与限流(redis熔断和限流)

本文将介绍如何使用Redis实现熔断和限流两个重要的微服务治理特性,以提高系统的稳定性和可靠性。微服务架构中的每个服务都有可能发生宕机、超时等问题,如果不对其进行一定的处理,可能会引发级联宕机问题。而进行熔断和限流可以在一定程度上避免此类问题的发生,同时也能提高整体系统的性能和可用性。

基于Redis的熔断

熔断是指当服务调用失败率或错误率达到一定阈值时,系统将自动停止调用该服务一段时间,以免进一步引发级联失败。基于Redis的熔断通常是通过记录服务的调用成功和失败次数,并且根据指定的失败阈值进行自动熔断和恢复。Redis提供了一个非常方便的atomic操作–“INCR”,可用于计数。

在spring-cloud中集成hystrix和redis的实现如下:

@Configuration
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class HystrixRedisAutoConfiguration {

@Autowired(required = false)
private List instanceFactories = Collections.emptyList();

@Autowired
private RedisCacheHelper redisCache;

@PostConstruct
public void init() {
HystrixPlugins.getInstance().registerCommandExecutionHook(new HystrixCommandExecutionHook() {
@Override
public T onEmit(HystrixInvokable commandInstance, T value) {
String name = commandInstance.getClass().getSimpleName();
if (commandInstance.isFledExecution()) {
redisCache.incr(name + ".flure.count");
} else {
redisCache.incr(name + ".success.count");
}
return super.onEmit(commandInstance, value);
}
});
instanceFactories.add(new HystrixCommandExecutionHookApplicationFactory());
}

public class HystrixCommandExecutionHookApplicationFactory implements HystrixCommandExecutionHook {
@Override
public T onEmit(HystrixInvokable commandInstance, T value) {
String name = commandInstance.getClass().getSimpleName();

Long successCount = redisCache.get(name + ".success.count");
Long flureCount = redisCache.get(name + ".flure.count");
if (successCount == null || flureCount == null) {
return value;
}
Long totalCount = successCount + flureCount;
Integer flurePercent = Math.toIntExact(flureCount * 100 / totalCount);

if (flurePercent > 50) {
throw new RuntimeException("Circuit Breaker: " + name + " is Open");
}
return value;
}
}
}

配置文件中增加:

hystrix.command.default.metrics.rollingPercentile.timeInMilliseconds: 60000
hystrix.command.default.metrics.rollingPercentile.numBuckets: 6
hystrix.command.default.fallbackIsolationSemaphoreMaxConcurrentRequests: 100
hystrix.command.default.circuitBreaker.requestVolumeThreshold: 20
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds: 5000
hystrix.command.default.circuitBreaker.errorThresholdPercentage: 50

基于Redis的限流

限流是指对服务的请求流量进行控制,当请求流量达到一定上限时,系统将自动拒绝多余的请求,以保证服务的稳定性和可靠性。基于Redis的限流通常是通过漏桶算法进行实现,即将请求放入一个“漏桶”中,利用Redis的List数据类型进行存储,通过pop操作来实现流量控制。

实现代码如下:

public class RedisLeakyBucket {
private final StringRedisTemplate stringRedisTemplate;

public RedisLeakyBucket(StringRedisTemplate stringRedisTemplate) {
this.stringRedisTemplate = stringRedisTemplate;
}

private static final String KEY_PREFIX = "Limit:LeakyBucket:";

/**
* 添加元素
*
* @param key key
* @param element 元素
* @param rate 漏桶限流速率,单位:秒
* @param limit 桶的大小
*/
public synchronized boolean add(String key, String element, int rate, int limit) {
long now = System.currentTimeMillis();

stringRedisTemplate.opsForList().rightPush(key, now + "");
stringRedisTemplate.expire(key, rate, TimeUnit.SECONDS);

Long size = stringRedisTemplate.opsForList().size(key);
if (size > limit) {
stringRedisTemplate.opsForList().leftPop(key);
size--;
}

return size
}
}

调用时:

@Autowired
private RedisLeakyBucket redisLeakyBucket;

public void test() {
boolean add = redisLeakyBucket.add("key", "element", 1, 100);
if (!add) {
throw new RuntimeException("抛出限流异常");
}
}

总结

本文主要介绍了如何使用Redis实现熔断和限流两个重要的微服务治理特性。熔断和限流可以在一定程度上避免系统出现级联宕机和性能瓶颈问题,提高系统的稳定性和可靠性。同时Redis提供了非常方便和高效的数据类型和命令,可以实现对服务的计数和限流控制。


数据运维技术 » 基于Redis优雅实现熔断与限流(redis熔断和限流)