自定义受保护的资源
- try…catch()
try(Entry entry = SphU.entry("seckillSkus")) {
///业务逻辑
}
2)基于注解
@SentinelResource(value = "getCurrentSeckillSkusResource", blockHandler = "blockHandler")
1 和 2 一定要配置被限流以后的默认返回
url,请求可以设置统一返回
在application.yml中添加
#开启feign sentinel 熔断保护
feign:
sentinel:
enabled: true
编写想要保护的资源
public List<SeckillSkuRedisTo> blockHandler(BlockException e) {
log.info("getCurrentSeckillSkusResource资源被限流了.");
return null;
}
/**
* 返回当前时间可以参与的秒杀商品信息
* 被保护资源 try (Entry entry = SphU.entry("seckillSkus")) {
* 被限流了就调用blockHandler = "blockHandler"方法
* fallback = ""针对异常的处理
*/
//定义被保护的资源
@SentinelResource(value = "getCurrentSeckillSkusResource", blockHandler = "blockHandler")
@Override
public List<SeckillSkuRedisTo> getCurrentSeckillSkus() {
//1 确定当前时间属于哪个秒杀场次
//当前时间
long now = new Date().getTime();
try (Entry entry = SphU.entry("seckillSkus")) {
Set<String> keys = redisTemplate.keys(SESSION_CACHE_PREFIX + "*");
for (String key : keys) {
//seckill:sessions:1613757600000_1613761200000
String replace = key.replace(SESSION_CACHE_PREFIX, "");
String[] s = replace.split("_");
long start = Long.parseLong(s[0]);
long end = Long.parseLong(s[1]);
if (start <= now && now <= end) {
//说明在当前场次的时间区间内
List<String> row = redisTemplate.opsForList().range(key, -100, 100);
//已修改 BoundHashOperations<String, Object, Object> hashOps = r
BoundHashOperations<String, String, String> hashOps = redisTemplate.boundHashOps(SKUKILL_CACHE_PREFIX);
List<String> list = hashOps.multiGet(row);
if (list != null) {
List<SeckillSkuRedisTo> collect = list.stream().map((item) -> {
SeckillSkuRedisTo to = JSON.parseObject((String) item, SeckillSkuRedisTo.class);
// to.setRandomCode(null);//当前秒杀开始就需要随机码
return to;
}).collect(Collectors.toList());
return collect;
}
break;
}
}
} catch (BlockException e) {
log.error("自定义被保护资源被限流-{}", e.getMessage());
}
return null;
}
只要这里做了流控限制,就会触发blockHandler方法里面的
log.info(“getCurrentSeckillSkusResource资源被限流了.”);