网站首页 > 精选教程 正文
在微服务中限流和熔断降级是必不可少的,SentinelResource不止提供了通过简单定义实现限流措施,同样提供了类似的方式实现熔断降级。其实现方式基本上同限流操作一致。
(一)创建资源点
熔断降级的资源点定义和限流一致,即对需要保护的方法上,添加SentinelResource注解。这里实现一个需求:接口记录用户访问的数量,等级用户访问时,直接抛出异常,模拟记录时的服务错误现象。
package com.ray.sentinel.resource;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class AccountService {
@SentinelResource(value = "userCountPoint")
public void count(String username) {
log.info("用户登录:{}", username);
throw new RuntimeException("统计登录人数失败");
}
}
(二)控制器中注册用户登录
package com.ray.sentinel.resource;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
public class UserController {
private final AccountService accountService;
@GetMapping("/user/count")
public String userCount() {
accountService.count(String.valueOf(System.currentTimeMillis()));
return "user is count";
}
}
(二) 启动服务并进行限流配置
启动Nacos、Sentinel同时启动sentinel-resource项目,并访问curl localhost:8074/user/count,这样Sentinel客户端可以创建资源点到Sentinel控制台。
curl localhost:8074/user/count
-- user is count
配置方式和限流配置基本上一致,只是选择降级按钮,我们先按照异常数进行配置,如下图所示,表明当异常数达到2时,在时间窗口5秒内,该资源点都会被降级,当超出时间窗口后,资源点访问恢复。
访问接口,当第三次访问时,控制台报出DegradeException异常,在此后的5秒内访问,均会报出降级异常,当5秒之后,接口继续抛出默认的异常信息。
2021-08-03 20:28:02.226 ERROR 21524 --- [nio-8074-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.reflect.UndeclaredThrowableException] with root cause
com.alibaba.csp.sentinel.slots.block.degrade.DegradeException: null
熔断降级异常处理
SentinelResource对降级的异常处理同限流异常处理基本上一致,支持在同类内指定方法和统一降级异常处理。首先使用fallback指定降级异常的处理方法,同时通过fallbackClass指定降级异常处理的统一类。
package com.ray.sentinel.resource;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.ray.sentinel.resource.fallback.AccountFallback;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class AccountService {
@SentinelResource(value = "userCountPoint", fallback = "countFallback", fallbackClass = AccountFallback.class)
public void count(String username) {
log.info("用户登录:{}", username);
throw new RuntimeException("统计登录人数失败");
}
}
创建AccountFallback对象,并完成异常处理。在同一异常处理类中,处理方法需要是静态的,同时入参与返回值需要同被保护的资源点一致。
package com.ray.sentinel.resource.fallback;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class AccountFallback {
public static void countFallback(String username, Throwable e) {
log.error("用户统计降级:{}", username, e);
}
}
完成降级异常处理后,启动服务并添加资源点降级策略,即可完成测试,此时因为降级被处理,不会再返回错误信息。查看控制台错误信息已被处理。
2021-08-04 10:27:34.684 ERROR 17360 --- [nio-8074-exec-1] c.r.s.resource.fallback.AccountFallback : 用户统计降级:1628044054615
java.lang.RuntimeException: 统计登录人数失败
对于以上降级的处理进行如下总结:
- 统一降级异常处理由fallback和fallbackClass两个配置共同组成,fallbackClass指定了哪些异常信息由哪些处理类来操作,fallback表明由哪个方法来操作异常信息。
- 当使用外部类操作异常信息时,fallback方法需要是静态方法。
- 处理方法的入参与返回值需要与被保护的资源点保持一致。可以额外添加一个Throwable参数,用于将异常信息传递到处理方法中,也可以不处理。
降级的三种配置
通过之前的降级配置过程,我们了解到Sentinel一共有三种降级方式:RT、异常比例、异常个数。
(一) RT
触发机制:当一秒内持续5个请求的平均响应时间大于阈值,触发降级。当超过时间窗口期限后,降级失效。
平均响应时间(DEGRADE_GRADE_RT):当一秒内持续进入N个请求,对应时刻的平均响应时间(秒)均超过阈值(单位为ms),那么之后持续时间窗口内(DegradeRule中的timeWindow参数,单位为s),对该资源点的调用都会自动熔断,并抛出DegradeException异常。
Sentinel默认RT的上限是4900毫秒,超过该阈值都会按4900毫秒处理,可以通过-Dcsp.sentinel.statistic.max.rt=xxxxx来进行调整。
为了测试该功能,借用上面的示例,降级异常处理不变,新增了一个业务方法,在该方法执行过程中,休眠350毫秒来模拟业务方法处理过慢的问题,同时新增了API来调用该方法,参考如下代码:
package com.ray.sentinel.resource;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.ray.sentinel.resource.fallback.AccountFallback;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
@Service
@Slf4j
public class AccountService {
@SentinelResource(value = "userCountPoint", fallback = "countFallback", fallbackClass = AccountFallback.class)
public void countForRt(String username) throws InterruptedException {
TimeUnit.MILLISECONDS.sleep(350);
log.info("用户登录:{}", username);
}
}
Controller中调用该方法。
package com.ray.sentinel.resource;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
public class UserController {
private final AccountService accountService;
@GetMapping("/user/rt")
public String userCountRt() throws InterruptedException {
accountService.countForRt(String.valueOf(System.currentTimeMillis()));
return "user is count";
}
}
启动服务,并创建资源点降级策略,如下所示
由于需要在一秒内发起超过5个请求,测试时使用了JMeter,设置并发10请求,在一秒内访问http://localhost:8074/user/rt该接口,并循环1000次。
观察控制台,发现超过上述配置后,引发降级,当时间窗口过期后,服务恢复,循环往复。
2021-08-04 11:16:48.121 ERROR 260 --- [o-8074-exec-110] c.r.s.resource.fallback.AccountFallback : 用户统计降级:1628047008121
com.alibaba.csp.sentinel.slots.block.degrade.DegradeException: null
(二) 异常比例
触发机制:当QPS大于等于5时,且异常比例超过了设定的阈值时,就会触发熔断降级。当超过时间窗口后,关闭降级。
异常比例(DEGRADE_GRADE_EXCEPTION_RATIO):当资源点的每秒请求量 >= N时,并且每秒的异常总数占通过量的比值超过阈值(DegradeRule中的数量)之后,资源点进入降级状态。在后续的时间窗口(DegradeRule中的timeWindow,单位为s)内,对该资源点的调用都会触发降级,直接返回;超出时间窗口后,降级关闭,请求恢复。异常比率的阈值取值范围为[0.0, 1.0],代表百分比。
对原来订单的资源点orderPoint进行异常比配置,当超过40%的异常比时,触发异常,如下图所示
仍然使用之前章节的用户登录记录模块,因为异常比是按照QPS进行计算,因此这里仍然使用JMeter,并发设置为10,在一秒内访问http://localhost:8074/user/count该接口,并循环1000次。
观察控制台,发现超过上述配置后,引发降级,当时间窗口过期后,服务恢复,循环往复。
2021-08-04 15:13:10.129 ERROR 6292 --- [nio-8074-exec-6] c.r.s.resource.fallback.AccountFallback : 用户统计降级:1628061190129
com.alibaba.csp.sentinel.slots.block.degrade.DegradeException: null
(二) 异常数
触发机制:当访问请求异常次数超过N次(阈值设定),则会触发熔断降级,在后续的时间窗口内,所有请求都会直接返回。当超过时间窗口后,降级被关闭,请求恢复。
异常数(DEGRADE_GRADE_EXCEPTION_COUNT):当资源点近一分钟的异常数目超过阈值之后,该资源点会被熔断降级。统计单位为分钟,若时间窗口小于60秒时,则超过时间窗口后,资源点仍然可能会进入熔断降级状态。
- 上一篇: 服务兜底方案之:服务降级和熔断实现
- 下一篇: 谈谈服务雪崩、降级与熔断
猜你喜欢
- 2024-11-17 SpringCloudAlibabaSentinel熔断限流
- 2024-11-17 2022届秋招Java岗高频面试题盘点,老司机也未必全会,真的太卷了
- 2024-11-17 2022春招,Java面试项目推荐,15个项目吃透两个offer拿到手软
- 2024-11-17 微服务网关如何防止雪崩?阿里开源项目之Sentinel限流、熔断
- 2024-11-17 SpringCloud之Hystrix服务降级
- 2024-11-17 分布式服务限流降级熔断解决方案Nacos之Dashboard界面配置含义
- 2024-11-17 2022年腾讯首发Java岗分布式面试真题,助力金三银四我是认真的
- 2024-11-17 一个可供参考的Java高并发异步应用案例--转
- 2024-11-17 面试官:聊聊服务熔断降级Sentinel
- 2024-11-17 2019年高级Java程序员面试题汇总,含个人答案总结
你 发表评论:
欢迎- 04-11Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- 04-11Java中你知道几种从字符串中找指定的字符的数量
- 04-11探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- 04-11Python字符串详解与示例(python字符串的常见操作)
- 04-11java正则-取出指定字符串之间的内容
- 04-11String s1 = new String("abc");这句话创建了几个字符串对象?
- 04-11java判断字符串中是否包含某个字符
- 04-11关于java开发中正确的发牌逻辑编写规范
- 最近发表
-
- Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- Java中你知道几种从字符串中找指定的字符的数量
- 探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- Python字符串详解与示例(python字符串的常见操作)
- java正则-取出指定字符串之间的内容
- String s1 = new String("abc");这句话创建了几个字符串对象?
- java判断字符串中是否包含某个字符
- 关于java开发中正确的发牌逻辑编写规范
- windows、linux如何后台运行jar(并且显示进程名)
- 腾讯大佬私人收藏,GitHub上最受欢迎的100个JAVA库,值得学习
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)