目录
在服务调用链路中, 服务提供者不可用, 导致服务调用者不可用, 间接让上上游也不可用, 这个不可用逐渐放大的过程, 叫做服务雪崩
1. 超时机制
2. 限流
3. 资源隔离(线程池/信号量隔离)
4. 熔断降级
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
官方文档: https://sentinelguard.io/zh-cn/docs/introduction.html
资源可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。在接下来的文档中,我们都会用资源来描述代码块。
围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。一个资源可以对应多个规则, 一个规则只能对应一个资源.
1. 引入maven依赖
- <dependency>
- <groupId>com.alibaba.cspgroupId>
- <artifactId>sentinel-coreartifactId>
- <version>1.8.6version>
- dependency>
2. 接口实现
- @RestController
- @Slf4j
- public class HelloController {
-
- // 定义资源名称
- private static final String RESOURCE_NAME = "HelloWorld";
-
- @RequestMapping(value = "/hello")
- public String hello() {
- // try catch包起来的代码块 就是资源
- try (Entry entry = SphU.entry(RESOURCE_NAME)) {
- // 被保护的逻辑
- log.info("hello world");
- return "hello world";
- } catch (BlockException ex) {
- // 自定义流控逻辑
- log.info("blocked!");
- return "被流控了";
- }
- }
- /**
- * 定义流控规则
- */
- @PostConstruct
- private static void initFlowRules(){
- List
rules = new ArrayList<>(); - FlowRule rule = new FlowRule();
- //设置受保护的资源
- rule.setResource(RESOURCE_NAME);
- // 设置流控规则 QPS
- rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
- // 设置受保护的资源阈值, qps>1 就被流控
- rule.setCount(1);
- rules.add(rule);
- // 加载配置好的规则
- FlowRuleManager.loadRules(rules);
- }
- }
存在缺点: 代码侵入太强, 不够灵活
1. 引入pom依赖, sentinel核心jar和切面jar
- <dependency>
- <groupId>com.alibaba.cspgroupId>
- <artifactId>sentinel-coreartifactId>
- <version>1.8.6version>
- dependency>
-
- <dependency>
- <groupId>com.alibaba.cspgroupId>
- <artifactId>sentinel-annotation-aspectjartifactId>
- <version>1.8.6version>
- dependency>
2. 注入切面类
- @Configuration
- public class SentinelAspectConfiguration {
-
- @Bean
- public SentinelResourceAspect sentinelResourceAspect() {
- return new SentinelResourceAspect();
- }
- }
3. 设置流控规则注解, 注解定义资源以及降级逻辑
- @PostConstruct
- private static void initFlowRules(){
- List
rules = new ArrayList<>(); - FlowRule rule = new FlowRule();
- //设置受保护的资源
- rule.setResource(RESOURCE_NAME);
- // 设置流控规则 QPS
- rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
- // 设置受保护的资源阈值
- rule.setCount(3);
- rules.add(rule);
- // 加载配置好的规则
- FlowRuleManager.loadRules(rules);
- }
-
- @SentinelResource(value = RESOURCE_NAME,
- blockHandler = "handleException",blockHandlerClass = ExceptionUtil.class,
- fallback = "fallbackException",fallbackClass = ExceptionUtil.class)
- @RequestMapping("/hello2")
- public String hello2() {
- int i = 1 / 0;
- return "helloworld ";
- }
- public class ExceptionUtil {
-
- public static String fallbackException(Throwable t){
- return "===被异常降级啦===";
- }
-
- public static String handleException(BlockException ex){
- return "===被限流啦===";
- }
- }
官方文档:https://sentinelguard.io/zh-cn/docs/dashboard.html
1. 下载控制台
https://github.com/alibaba/Sentinel/releases/download/1.8.7/sentinel-dashboard-1.8.7.jar
2. 启动控制台
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.7.jar
3. 登录控制台
访问http://localhost:8080/#/login ,默认用户名密码: sentinel/sentinel
1. 引入sentinel通信jar
- <dependency>
- <groupId>com.alibaba.cspgroupId>
- <artifactId>sentinel-transport-simple-httpartifactId>
- <version>1.8.6version>
- dependency>
2. java应用增加启动参数, 启动服务
-Dproject.name=kk-sentinel-demo -Dcsp.sentinel.dashboard.server=localhost:8080 -Dcsp.sentinel.api.port=8719
3. 访问流控接口http://localhost:8800/hello, 登录控制台检查
4. 控制台修改流控规则, 接口测试, 实时生效
5. get接口查看流控规则, url = http://localhost:8720/getRules?type=flow
1. 引入pom依赖
-
- <dependency>
- <groupId>com.alibaba.cloudgroupId>
- <artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
- dependency>
-
-
-
- <dependency>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-starter-actuatorartifactId>
- dependency>
2. 修改yml配置
- server:
- port: 8800
-
- feign:
- sentinel:
- enabled: true #开启Sentinel 对 Feign 的支持
-
- spring:
- application:
- name: mall-user
- cloud:
- nacos:
- discovery:
- server-addr: 127.0.0.1:8848
-
- sentinel:
- transport:
- # 添加sentinel的控制台地址
- dashboard: 127.0.0.1:8080
- # 指定应用与Sentinel控制台交互的端口,应用会起一个HttpServer占用该端口
- # port: 8719
-
- #暴露actuator端点 http://localhost:8800/actuator/sentinel
- management:
- endpoints:
- web:
- exposure:
- include: '*'
3. 对URL流控
- // 对URL流控
- @RequestMapping("/info/{id}")
- @SentinelResource(value = "userinfo", blockHandler = "handleException")
- public R info(@PathVariable("id") Integer id){
- UserEntity user = userService.getById(id);
- if(id==4){
- throw new IllegalArgumentException("异常参数");
- }
-
- return R.ok().put("user", user);
- }
-
- // 对子方法流控
- @SentinelResource(value = "getUser",blockHandler = "handleException")
- public UserEntity getById(Integer id) {
- return userDao.getById(id);
- }
4. 接入openFeign 熔断降级
- @FeignClient(value = "mall-order",path = "/order",fallbackFactory = FallbackOrderFeignServiceFactory.class)
- public interface OrderFeignService {
-
- @RequestMapping("/findOrderByUserId/{userId}")
- public R findOrderByUserId(@PathVariable("userId") Integer userId);
- }
-
-
-
- @Component
- public class FallbackOrderFeignServiceFactory implements FallbackFactory
{ - @Override
- public OrderFeignService create(Throwable throwable) {
- return new OrderFeignService() {
- @Override
- public R findOrderByUserId(Integer userId) {
- return R.error(-1,"=======服务降级了========");
- }
- };
- }
- }