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依赖
XML 复制代码
<dependency>
     <groupId>com.alibaba.csp</groupId>
     <artifactId>sentinel-core</artifactId>
     <version>1.8.6</version>
</dependency>
  1. 接口实现
java 复制代码
@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<FlowRule> 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);
    }
}

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

@SentinelResource注解实现

  1. 引入pom依赖, sentinel核心jar和切面jar
XML 复制代码
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-core</artifactId>
            <version>1.8.6</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-annotation-aspectj</artifactId>
            <version>1.8.6</version>
        </dependency>
  1. 注入切面类
java 复制代码
@Configuration
public class SentinelAspectConfiguration {

    @Bean
    public SentinelResourceAspect sentinelResourceAspect() {
        return new SentinelResourceAspect();
    }
}
  1. 设置流控规则注解, 注解定义资源以及降级逻辑
java 复制代码
    @PostConstruct
    private static void initFlowRules(){
        List<FlowRule> 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 ";
    }
java 复制代码
public class ExceptionUtil {

    public static String fallbackException(Throwable t){
        return "===被异常降级啦===";
    }

    public static String handleException(BlockException ex){
        return "===被限流啦===";
    }
}

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

  1. 启动控制台

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.7.jar

  1. 登录控制台

访问http://localhost:8080/#/login ,默认用户名密码: sentinel/sentinel

java应用接入控制台

  1. 引入sentinel通信jar
XML 复制代码
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-transport-simple-http</artifactId>
            <version>1.8.6</version>
        </dependency>
  1. java应用增加启动参数, 启动服务

-Dproject.name=kk-sentinel-demo -Dcsp.sentinel.dashboard.server=localhost:8080 -Dcsp.sentinel.api.port=8719

  1. 访问流控接口http://localhost:8800/hello, 登录控制台检查
  1. 控制台修改流控规则, 接口测试, 实时生效
  1. get接口查看流控规则, url = http://localhost:8720/getRules?type=flow

微服务接入Sentinel

  1. 引入pom依赖
XML 复制代码
        <!--sentinel -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>


        <!-- 对外暴露的 Endpoint -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
  1. 修改yml配置
cs 复制代码
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: '*'
  1. 对URL流控
java 复制代码
    // 对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);
    }
  1. 接入openFeign 熔断降级
java 复制代码
@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<OrderFeignService> {
    @Override
    public OrderFeignService create(Throwable throwable) {
        return new OrderFeignService() {
            @Override
            public R findOrderByUserId(Integer userId) {
                return R.error(-1,"=======服务降级了========");
            }
        };
    }
}
相关推荐
2401_857439691 小时前
SpringBoot在线教育平台:设计与实现的深度解析
java·spring boot·后端
总是学不会.1 小时前
SpringBoot项目:前后端打包与部署(使用 Maven)
java·服务器·前端·后端·maven
IT学长编程1 小时前
计算机毕业设计 视频点播系统的设计与实现 Java实战项目 附源码+文档+视频讲解
java·spring boot·毕业设计·课程设计·毕业论文·计算机毕业设计选题·视频点播系统
一 乐2 小时前
英语词汇小程序小程序|英语词汇小程序系统|基于java的四六级词汇小程序设计与实现(源码+数据库+文档)
java·数据库·小程序·源码·notepad++·英语词汇
曳渔2 小时前
Java-数据结构-反射、枚举 |ू・ω・` )
java·开发语言·数据结构·算法
laocooon5238578862 小时前
java 模拟多人聊天室,服务器与客户机
java·开发语言
风槐啊3 小时前
六、Java 基础语法(下)
android·java·开发语言
苹果醋33 小时前
毕业设计_基于SpringBoot+vue的社区博客系统【源码+SQL+教程+可运行】41002
java·毕业设计·博客
冬天vs不冷3 小时前
SpringBoot基础(四):bean的多种加载方式
java·spring boot·spring
说书客啊3 小时前
计算机毕业设计 | SpringBoot+vue学生成绩管理系统教务管理系统
java·spring boot·node.js·vue·毕业设计·课程设计·教务管理系统