初识Spring Cloud系列——Sentinel原理

904 阅读3分钟

这是我参与更文挑战的第25天,活动详情查看: 更文挑战

今天我们来了解一下一个新的微服务件Sentinel,它的作用其实跟Hytrix有些雷同,关于Hystrix,可以看看小编之前的文章初识Spring Cloud系列——Hystrix原理

回到今天的主角Sentinel

什么是Sentinel?

sentinel历史

  • 2012年,sentinel诞生,主要功能为入口流量控制
  • 2013-2017年,sentinel在阿里集团内部使用
  • 2018年开源

Sentinel的作用?

Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

资源

所谓资源,指的是说通过Sentinel API定义的代码,成为资源,就能够被Sentinel保护起来

规则

根据资源的实时状态来设定规则,有(规则可以按需动态实时调整)

  • 流量控制规则
  • 熔断降级规则
  • 系统保护规则
资源与规则实战例子

SphU

Entry entry = null;
try {
    entry = SphU.entry(KEY);
    System.out.println("entry ok...");
} catch (BlockException e1) {
    // 获取限流资源失败
} catch (Exception e2) {
    // biz exception
} finally {
    if (entry != null) {
        entry.exit();
    }
}

SphO

Entry entry = null;
if (SphO.entry(KEY)) {
    System.out.println("entry ok");
} else {
    // 获取限流资源失败
}

sentinel中调用sphu或者spho的entry方法获取限流资源,不同的是前者获取限流资源失败时会抛blockexception异常,后者或捕获该异常并返回false

从0.1.1版本开始,sentinel加入了注解(@SentinelResource)的支持,可以通过注解来定义资源 可以参考@SentinelResource注解使用详解

流量控制

Sentinel作为一个调配器的角色,能根据需要把随机不可控的请求调整成合适的请求量 具体调整内容 根据资源的调用关系 系统服务的运行指标,比如QPS、线程池的连接数、系统负载 采取直接限流、冷启动、排队等方式来达到控制的效果

熔断降级

当调用链路中出现某个不稳定的资源时,对该资源的调用进行限制,并让请求快速失败,避免影响其它资源产生雪崩效果

Sentinel 的主要特性

image.png

Sentinel、Hystrix以及resilience4j的区别

image.png

  • 隔离策略 Sentinel是信号量隔离,Hystrix则是线程池隔离或信号量隔离这两种
  • 熔断降级策略 Sentinel基于响应时间、异常比率、异常数;Hystrix基于异常比率;

相比之下,Sentinel的熔断降级策略更加广泛灵活一些

Sentinel 两个组成部分

核心库(Java 客户端)

不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。

控制台(Dashboard)

基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。

Sentinel实战

github下载sentinel对应版本dashboard的jar包 image.png 运行并访问http://localhsot:8080 image.png image.png

核心库(Java 客户端)的使用

建立新的项目模块alibaba-sentinel-service

image.png

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>study</artifactId>
        <groupId>brief.talk.spring.cloud</groupId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>alibaba-sentinel-service</artifactId>
    <dependencies>
        <!--SpringCloud ailibaba nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--SpringCloud ailibaba sentinel-datasource-nacos 后续做持久化用到-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>
        <!--SpringCloud ailibaba sentinel -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!--openfeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- SpringBoot整合Web组件+actuator -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--日常通用jar包配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>4.6.3</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

</project>

主程序

package brief.talk.spring.cloud;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@EnableDiscoveryClient
@SpringBootApplication
public class SentinelServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(SentinelServiceApplication.class, args);
    }
    @RestController
    class SentinelServiceController{

        @Value("${server.port}")
        private String port;
        @Value("${spring.application.name}")
        private String name;

        @GetMapping("/instanceInfo")
        public String echo(){
            return "port: " + port + ", instance name is " + name;
        }

    }

}

运行步骤

先启动nacos

image.png 然后启动alibaba-sentinel-service项目

访问浏览器nacos

image.png

调用instanceInfo接口

访问http://localhost:8901/instanceInfo image.png

刷新Sentinel dashboard页面

image.png

Sentinel小demo测通!!!

今日小结 今天主要了解了Sentinel的原理、特性,还用sentinel两个部分核心库(Java 客户端)和控制台(Dashboard)的使用,好了,再见!