• Sentinel实战(待完善)


    目录

    服务雪崩

    什么是服务雪崩

    服务不可用原因

    解决方案

    技术选型对比

    Sentinel

    介绍

    优点

    核心概念

    资源

    规则

    代码实战

    API实现

    @SentinelResource注解实现

    Sentinel控制台

    启动控制台服务

    java应用接入控制台

    微服务接入Sentinel


    服务雪崩

    什么是服务雪崩

            在服务调用链路中, 服务提供者不可用, 导致服务调用者不可用, 间接让上上游也不可用, 这个不可用逐渐放大的过程, 叫做服务雪崩

    服务不可用原因

    • 内存泄漏
    • 大流量请求, 超过正常承受qps
    • 缓存击穿, 大量直接打到数据库
    • 硬件损坏

    解决方案

    1. 超时机制

    2. 限流

    3. 资源隔离(线程池/信号量隔离)

    4. 熔断降级

    技术选型对比

    Sentinel

    介绍

            随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。

    官方文档: https://sentinelguard.io/zh-cn/docs/introduction.html

    优点

    • 丰富的应用场景: Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、实时熔断下游不可用应用等。
    • 完备的实时监控: Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
    • 广泛的开源生态: Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
    • 完善的 SPI 扩展点: Sentinel 提供简单易用、完善的 SPI 扩展点。您可以通过实现扩展点,快速的定制逻辑。例如定制规则管理、适配数据源等。

    核心概念

    资源

            资源可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。在接下来的文档中,我们都会用资源来描述代码块。

    规则

            围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。一个资源可以对应多个规则, 一个规则只能对应一个资源.

    代码实战

    API实现

    1. 引入maven依赖

    1. <dependency>
    2. <groupId>com.alibaba.cspgroupId>
    3. <artifactId>sentinel-coreartifactId>
    4. <version>1.8.6version>
    5. dependency>

    2. 接口实现

    1. @RestController
    2. @Slf4j
    3. public class HelloController {
    4. // 定义资源名称
    5. private static final String RESOURCE_NAME = "HelloWorld";
    6. @RequestMapping(value = "/hello")
    7. public String hello() {
    8. // try catch包起来的代码块 就是资源
    9. try (Entry entry = SphU.entry(RESOURCE_NAME)) {
    10. // 被保护的逻辑
    11. log.info("hello world");
    12. return "hello world";
    13. } catch (BlockException ex) {
    14. // 自定义流控逻辑
    15. log.info("blocked!");
    16. return "被流控了";
    17. }
    18. }
    19. /**
    20. * 定义流控规则
    21. */
    22. @PostConstruct
    23. private static void initFlowRules(){
    24. List rules = new ArrayList<>();
    25. FlowRule rule = new FlowRule();
    26. //设置受保护的资源
    27. rule.setResource(RESOURCE_NAME);
    28. // 设置流控规则 QPS
    29. rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    30. // 设置受保护的资源阈值, qps>1 就被流控
    31. rule.setCount(1);
    32. rules.add(rule);
    33. // 加载配置好的规则
    34. FlowRuleManager.loadRules(rules);
    35. }
    36. }

    存在缺点: 代码侵入太强, 不够灵活

    @SentinelResource注解实现

    1. 引入pom依赖, sentinel核心jar和切面jar 

    1. <dependency>
    2. <groupId>com.alibaba.cspgroupId>
    3. <artifactId>sentinel-coreartifactId>
    4. <version>1.8.6version>
    5. dependency>
    6. <dependency>
    7. <groupId>com.alibaba.cspgroupId>
    8. <artifactId>sentinel-annotation-aspectjartifactId>
    9. <version>1.8.6version>
    10. dependency>

    2. 注入切面类

    1. @Configuration
    2. public class SentinelAspectConfiguration {
    3. @Bean
    4. public SentinelResourceAspect sentinelResourceAspect() {
    5. return new SentinelResourceAspect();
    6. }
    7. }

    3. 设置流控规则注解, 注解定义资源以及降级逻辑 

    1. @PostConstruct
    2. private static void initFlowRules(){
    3. List rules = new ArrayList<>();
    4. FlowRule rule = new FlowRule();
    5. //设置受保护的资源
    6. rule.setResource(RESOURCE_NAME);
    7. // 设置流控规则 QPS
    8. rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    9. // 设置受保护的资源阈值
    10. rule.setCount(3);
    11. rules.add(rule);
    12. // 加载配置好的规则
    13. FlowRuleManager.loadRules(rules);
    14. }
    15. @SentinelResource(value = RESOURCE_NAME,
    16. blockHandler = "handleException",blockHandlerClass = ExceptionUtil.class,
    17. fallback = "fallbackException",fallbackClass = ExceptionUtil.class)
    18. @RequestMapping("/hello2")
    19. public String hello2() {
    20. int i = 1 / 0;
    21. return "helloworld ";
    22. }
    1. public class ExceptionUtil {
    2. public static String fallbackException(Throwable t){
    3. return "===被异常降级啦===";
    4. }
    5. public static String handleException(BlockException ex){
    6. return "===被限流啦===";
    7. }
    8. }

    Sentinel控制台

    启动控制台服务

     官方文档: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

    java应用接入控制台

    1. 引入sentinel通信jar

    1. <dependency>
    2. <groupId>com.alibaba.cspgroupId>
    3. <artifactId>sentinel-transport-simple-httpartifactId>
    4. <version>1.8.6version>
    5. 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 

     

    微服务接入Sentinel

    1. 引入pom依赖

    1. <dependency>
    2. <groupId>com.alibaba.cloudgroupId>
    3. <artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
    4. dependency>
    5. <dependency>
    6. <groupId>org.springframework.bootgroupId>
    7. <artifactId>spring-boot-starter-actuatorartifactId>
    8. dependency>

    2. 修改yml配置

    1. server:
    2. port: 8800
    3. feign:
    4. sentinel:
    5. enabled: true #开启Sentinel 对 Feign 的支持
    6. spring:
    7. application:
    8. name: mall-user
    9. cloud:
    10. nacos:
    11. discovery:
    12. server-addr: 127.0.0.1:8848
    13. sentinel:
    14. transport:
    15. # 添加sentinel的控制台地址
    16. dashboard: 127.0.0.1:8080
    17. # 指定应用与Sentinel控制台交互的端口,应用会起一个HttpServer占用该端口
    18. # port: 8719
    19. #暴露actuator端点 http://localhost:8800/actuator/sentinel
    20. management:
    21. endpoints:
    22. web:
    23. exposure:
    24. include: '*'

    3. 对URL流控

    1. // 对URL流控
    2. @RequestMapping("/info/{id}")
    3. @SentinelResource(value = "userinfo", blockHandler = "handleException")
    4. public R info(@PathVariable("id") Integer id){
    5. UserEntity user = userService.getById(id);
    6. if(id==4){
    7. throw new IllegalArgumentException("异常参数");
    8. }
    9. return R.ok().put("user", user);
    10. }
    11. // 对子方法流控
    12. @SentinelResource(value = "getUser",blockHandler = "handleException")
    13. public UserEntity getById(Integer id) {
    14. return userDao.getById(id);
    15. }

    4. 接入openFeign 熔断降级

    1. @FeignClient(value = "mall-order",path = "/order",fallbackFactory = FallbackOrderFeignServiceFactory.class)
    2. public interface OrderFeignService {
    3. @RequestMapping("/findOrderByUserId/{userId}")
    4. public R findOrderByUserId(@PathVariable("userId") Integer userId);
    5. }
    6. @Component
    7. public class FallbackOrderFeignServiceFactory implements FallbackFactory {
    8. @Override
    9. public OrderFeignService create(Throwable throwable) {
    10. return new OrderFeignService() {
    11. @Override
    12. public R findOrderByUserId(Integer userId) {
    13. return R.error(-1,"=======服务降级了========");
    14. }
    15. };
    16. }
    17. }

  • 相关阅读:
    Leetcode《图解数据结构》刷题日志【第二周】(2022/10/24-2022/10/30)
    数据仓库之BI
    使用 CSS 的仿 GitHub 登录页面
    基于matlab实现AUTOSAR软件开发---答疑1
    matlab GUI制作界面的一些笔记(入门)
    BusyBox编译时选择合适的编译器
    记录一次关于嵌套事务传播机制的bug
    ChatGPT 上线 Canva 插件,可生成图片和视频内容
    【matplotlib基础】--动画
    C语言学习1==gcc 创建动态库
  • 原文地址:https://blog.csdn.net/weixin_64027360/article/details/136334536