Sentinel: 分布式系统的流量防卫兵
Sentinel 是什么?
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Sentinel 具有以下特征:
- 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
- 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
- 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
- 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
当然了 Senteal不仅仅是用来限流的 我们慢慢研究 最开始先实现简单功能,会用才是最重要的
首先自己去创建一个springboot项目(别问我为什么不是springcloud项目,cloud并不是框架,他是微服务的解决方案,是方案! 用到的框架其实就是springboot)
不会建的话就随便就创建一个maven项目就行
引入pom文件 直接复制我的(注意观察我的pom 做好版本控制在微服务项目中很重要),这就是我们所需要引入的所有pom
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
<spring-boot.version>2.3.5.RELEASE</spring-boot.version>
<spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!--spring boot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringCloud Alibaba -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
下面是我的项目启动类(没什么特别的)
@SpringBootApplication
public class BusinessInitializeApplication {
public static void main(String[] args) {
SpringApplication.run(BusinessInitializeApplication.class, args);
}
}
下面是我的请求类(重点是这里,如果要实现某个接口的限流监听就需要加@SentinelResource注解,value是资源名,blockHandler是我们定义的异常处理方法,其实还有一个参数可以指定异常处理类,这里我们为了方便就写在一个类里了,所以就不需要那个参数了)
@Controller
@RequestMapping("/Test")
public class TestCloud {
@SentinelResource(value = "res" ,blockHandler = "handleException")
@RequestMapping(value = "/upload")
@ResponseBody
public String logUpload(){
return "upload";
}
public String handleException(BlockException ex) {
System.out.println("被限流了");
return “恭喜你被限流了" ;
}
}
下面是我们项目的配置文件application.properties(啥都没有 这几个配置就是用来注册sentinel监听服务的)
spring.application.name=sentinel-WangZC
server.port=18083
spring.cloud.sentinel.transport.dashboard=localhost:8080
然后我们需要去官网下载sentinel的jar包(官网提供两种方式一种是下载源码去启动,一种是直接下载jar包启动,我们选择后者)
下载完成后直接 java -jar sentinel-dashboard.jar 启动sentinel 服务(放心,肯定会启动成功的)
然后访问控制台http://localhost:8080/
看到下面这个了吧 sentinel-WangZC就是我自己的实例
这个时候你需要先请求一下自己刚才写的那个接口 (sentinel是懒加载)才会看到自己要控制的那个限流资源(如下图)
然后我们点击控流(为了方便测试我们设置qps为1)然后点击新增
这个时候就可以测试了
考验手速的时候到了,利用你的鼠标后回车键飞速的请求你的那个接口http://localhost:18083/Test/upload
正常会返回这个
当你每秒请求超过一次后
这样我们就完成了整个限流的功能,点个赞再走呗
有个问题就是Sentinel的规则在项目重启后就会消失
我发现一个解决方案就是通过spring的自动装配 通过代码注入 这样的话项目启动后规则会自动加载
@Configuration
public class SentinelMsg {
@Bean
public void setSenteal() {
System.out.println("加载");
List<FlowRule> rules = new ArrayList<FlowRule>();
FlowRule rule = new FlowRule();
rule.setResource("res");
rule.setCount(2);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setLimitApp("default");
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
}
这样的缺点就是代码是写死的,如果规则经常改变的话就不太好维护了
官方的方法好像是持久化到nacos里面,我觉得这才是最合理的
好像还可以持久化到redis中