简介

一、什么是Sentinel?

雪崩效应
image.png
解决方式:
1.线程超时:设置一个范围,超过时间后释放线程

2.设置限流

3.熔断器Sentinel、Hystrix

  • 降级
  • 限流
  • 熔断

image.png

使用Sentinel

安装启动Sentinel

下载sentinel包,可以去github上拉取,也可直接使用吉力整理的资源
sentinel-dashboard.rar

解压后直接用java -jar命令启动,端口默认的为8080
image.png

访问http://localhost:8080,出现页面表示启动成功,默认的账号密码都为sentinel
image.png

配置Sentinel

在pom.xml中添加

  1. <dependency>
  2. <groupId>com.alibaba.cloud</groupId>
  3. <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
  4. <version>2.2.1.RELEASE</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter-actuator</artifactId>
  9. </dependency>

在application.yaml添加

  1. spring:
  2. cloud:
  3. nacos:
  4. discovery:
  5. server-addr: localhost:8848
  6. sentinel:
  7. transport:
  8. dashboard: localhost:8080
  9. application:
  10. name: provider
  11. server:
  12. port: 8081
  13. #开放服务接口
  14. management:
  15. endpoints:
  16. web:
  17. exposure:
  18. include: '*'

运行provider服务,并访问provider服务的/index接口,sentinel便可以捕获到
image.png

  • 资源名:请求的资源名称
  • QPS:每秒请求数量
  • 线程数:并发处理的线程数量
  • 单机阈值:限制的请求数量或者线程数量

限流规则

直接限流

流控模式-直接-QPS
点击 “簇点链路”==>”流控”
image.png
设置QPS为1,表示每秒通过请求数为1
image.png

当重复请求超过1时便会限流,如下图
image.png

关联限流

流控模式-关联-QPS

  • 关联模式:假设有两个接口/index/list,阈值为1,当请求/list接口的QPS超过1时便对/index接口进行限流处理

image.png

新增接口/list

  1. @GetMapping("/list")
  2. public String list(){
  3. return this.port+"list";
  4. }

新增测试类test作为模拟请求/list以便观看/index接口效果

  1. package com.jili.test;
  2. import org.springframework.web.client.RestTemplate;
  3. public class test {
  4. public static void main(String[] args) throws Exception {
  5. RestTemplate restTemplate =new RestTemplate();
  6. for(int i =0;i<1000 ;i++){
  7. restTemplate.getForObject("http://localhost:8081/list",String.class);
  8. Thread.sleep(200);
  9. }
  10. }
  11. }

每200ms启动一次,相当于1s启动5次超过了阈值1,/index接口会被限流
image.pngimage.png

链路限流

一般来说只能捕获controller层的服务,链路限流则可以控制service层

由于版本过高,我们需要手动关闭全部敛收的功能

在pom.xml引入

  1. <dependency>
  2. <groupId>com.alibaba.csp</groupId>
  3. <artifactId>sentinel-core</artifactId>
  4. <version>1.7.1</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.alibaba.csp</groupId>
  8. <artifactId>sentinel-web-servlet</artifactId>
  9. <version>1.7.1</version>
  10. </dependency>

在yaml里配置
spring.cloud.sentinel.filter.enabled = false

  1. spring:
  2. cloud:
  3. nacos:
  4. discovery:
  5. server-addr: localhost:8848
  6. sentinel:
  7. transport:
  8. dashboard: localhost:8080
  9. filter:
  10. enabled: false

新建配置类FilterConfiguration来开放链路
FilterConfiguration.java

  1. package com.jili.controller;
  2. import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter;
  3. import org.springframework.boot.web.servlet.FilterRegistrationBean;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. @Configuration
  7. public class FilterConfiguration {
  8. @Bean
  9. public FilterRegistrationBean registrationBean(){
  10. FilterRegistrationBean registrationBean = new FilterRegistrationBean();
  11. registrationBean.setFilter(new CommonFilter());
  12. registrationBean.addUrlPatterns("/*");
  13. registrationBean.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY,"false");
  14. registrationBean.setName("sentinelFilter");
  15. return registrationBean;
  16. }
  17. }

创建service层ProviderService

  1. package com.jili.service;
  2. import com.alibaba.csp.sentinel.annotation.SentinelResource;
  3. import org.springframework.stereotype.Service;
  4. @Service
  5. public class ProviderService {
  6. //Sentinel里捕获的名称
  7. @SentinelResource("test")
  8. public void test(){
  9. System.out.println("test");
  10. }
  11. }

在ProviderController.java加入两个测试接口

  1. @Autowired
  2. private ProviderService providerService;
  3. @GetMapping("/test1")
  4. public String test1(){
  5. this.providerService.test();
  6. return "test1";
  7. }
  8. @GetMapping("/test2")
  9. public String test2(){
  10. this.providerService.test();
  11. return "test2";
  12. }

此时/test1 与 /test2 都调用同一个service
image.png
访问http://localhost:8081/tes1与http://localhost:8081/tes2
此时sentinel系统显示
image.png