• springboot整合sentinel接口熔断


    背景

    请求第三方接口或者慢接口需要增加熔断处理,避免因为慢接口qps过大导致应用大量工作线程陷入阻塞以至于其他正常接口都不可用,最近项目测试环境就因为一个查询的慢接口调用次数过多,导致前端整个首页都无法加载。

    依赖下载

    • springboot
    <parent>
    	<groupId>org.springframework.bootgroupId>
    	<artifactId>spring-boot-starter-parentartifactId>
    	<version>2.6.3version>
    parent>
    <dependency>
    	<groupId>org.springframework.bootgroupId>
    	<artifactId>spring-boot-starter-webartifactId>
    dependency>
    
    • sentinel dashboard
      下载地址:
      https://github.com/alibaba/Sentinel/releases
      版本:
      sentinel-dashboard-1.8.3.jar
      启动命令:
      java -Dserver.port=9000 -Dcsp.sentinel.dashboard.server=localhost:9000 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.3.jar
    • sentinel springboot 依赖
    <dependency>
    	<groupId>com.alibaba.cloudgroupId>
    	<artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
    	<version>2021.0.1.0version>
    dependency>
    

    熔断尝试

    使用SentinelResource注解

    • 编写慢接口
    @RestController
    @RequestMapping(path = "/user")
    @RequiredArgsConstructor
    @Slf4j
    public class UserCtrl {
    
        private final IUserService userService;
    
        @GetMapping("/{id}")
        @SneakyThrows
        @SentinelResource(value = "findById", fallback = "findByIdExt")
        public User findById(@PathVariable("id") Long id) {
            TimeUnit.SECONDS.sleep(3);
            return userService.findById(id);
        }
    
        public User findByIdExt(Long id) {
            log.error("触发熔断");
            throw new IllegalStateException(String.format("id[{}]触发熔断", id));
        }
    }
    
    • 应用注册到sentinel dashboard
      添加jvm启动参数:-Dcsp.sentinel.dashboard.server=${sentinel-dashboard域名}:9000
      指定客户端监控 API 的端口(默认是 8719)-Dcsp.sentinel.api.port=8720
      在这里插入图片描述

    • 启动应用,进行一次接口调用
      Sentinel 会在客户端首次调用的时候进行初始化,开始向控制台发送心跳包。
      在这里插入图片描述

    • 配置熔断规则
      在这里插入图片描述在这里插入图片描述

    • 效果
      快速调用3次慢接口,可以看到触发熔断
      在这里插入图片描述在这里插入图片描述10秒熔断失效后可再次成功访问

    不使用SentinelResource注解

    • 慢接口代码
    @RestController
    @RequestMapping(path = "/user")
    @RequiredArgsConstructor
    @Slf4j
    public class UserCtrl {
    
        private final IUserService userService;
    
        @GetMapping("/{id}")
        @SneakyThrows
        public User findById(@PathVariable("id") Long id) {
            TimeUnit.SECONDS.sleep(3);
            return userService.findById(id);
        }
    
    }
    
    • 配置熔断规则
      在这里插入图片描述
      在这里插入图片描述
    • 效果
      快速访问多次慢接口
      在这里插入图片描述
    • 对熔断统一添加异常处理
    import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
    import com.alibaba.csp.sentinel.slots.block.BlockException;
    import com.alibaba.fastjson.JSON;
    import com.test.test.model.R;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.http.HttpStatus;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * @description sentinel 降级处理
     * @date 2024/6/14
     */
    @Slf4j
    public class WebBlockExceptionHandler implements BlockExceptionHandler {
    
        @Override
        public void handle(HttpServletRequest httpServletRequest, HttpServletResponse response, BlockException e) throws Exception {
            log.error(String.format("sentinel 降级 资源名称%s", e.getRule().getResource()), e);
    
            response.setContentType("application/json");
            response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
            response.getWriter().print(JSON.toJSON(R.err(e.getMessage())));
        }
    }
    
    import com.alibaba.cloud.sentinel.feign.SentinelFeignAutoConfiguration;
    import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
    import com.test.test.hanlder.WebBlockExceptionHandler;
    import org.springframework.boot.autoconfigure.AutoConfigureBefore;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * @description
     * @date 2024/6/14
     */
    @Configuration(proxyBeanMethods = false)
    @AutoConfigureBefore(SentinelFeignAutoConfiguration.class)
    public class SentinelAutoConfiguration {
    
        @Bean
        @ConditionalOnMissingBean
        public BlockExceptionHandler blockExceptionHandler() {
            return new WebBlockExceptionHandler();
        }
    }
    
    • 统一降级异常处理效果
      在这里插入图片描述在这里插入图片描述
  • 相关阅读:
    RabbitMQ快速入门
    vue中封装websocket,全局调用
    【Transformer从零开始代码实现 pytoch版】(二)Encoder编码器组件:mask+attention+feed forward+add&norm
    2022六边形JAVA面试八股文分享,我这一拳20年的功力你接得住吗?
    只出现一次的数字
    宠物品牌新媒体推广有哪些技巧和方法
    计算机毕业设计springboot+vue基本微信小程序的码高教育课后在线小程序
    《Python+Kivy(App开发)从入门到实践》自学笔记:高级UX部件——Popup弹窗
    2022 年最新版 68 道 Redis 面试题,20000 字,赶紧收藏起来备用
    springboot vue街球社区网站java
  • 原文地址:https://blog.csdn.net/qq_41633199/article/details/139659955