sentinel

111 阅读7分钟

一、基础概念

服务限流/熔断

服务限流目的是为了更好的保护我们的服务,在高并发的情况下,如果客户端请求的数量达到一定极限(后台可以配置阈值),请求的数量超出了设置的阈值,开启自我的保护,直接调用我们的服务降级的方法,不会执行业务逻辑操作,直接走本地falback的方法,返回一个友好的提示

服务降级

在高并发的情况下, 防止用户一直等待,采用限流/熔断方法,使用服务降级的方式返回一个友好的提示给客户端,不会执行业务逻辑请求,直接走本地的falback的方法。eg: 提示语:当前排队人数过多,稍后重试~

服务的雪崩效应

默认的情况下,Tomcat或者是Jetty服务器只有一个线程池去处理客户端的请求,
这样的话就是在高并发的情况下,如果客户端所有的请求都堆积到同一个服务接口上,
那么就会产生tomcat服务器所有的线程都在处理该接口,可能会导致其他的接口无法访问。

eg: 假设我们的tomcat线程最大的线程数量是为20,这时候客户端如果同时发送100个请求会导致有80个请求暂时无法访问,就会转圈。

服务雪崩的解决方案:服务的隔离的机制

服务的隔离机制分为信号量和线程池隔离模式

  • 服务的线程池隔离机制:每个服务接口都有自己独立的线程池,互不影响,缺点就是占用cpu资源非常大。
  • 服务的信号量隔离机制:最多只有一定的阈值线程数处理我们的请求,超过该阈值会拒绝请求。

二、Sentinel与hytrix区别

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

前哨具有以下特征:

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

Sentinel中文文档介绍:sentinel中文文档

Sentinel与hytrix区别

三、SpringBoot项目整合Sentinel

1.Maven依赖的配置

| 1 2 3 4 5 6 7 8 9 10 | ``` org.springframework.cloud spring-cloud-alibaba-sentinel 0.2.2.RELEASE org.springframework.boot spring-boot-starter-actuator

| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

#### [](#2-%E9%A1%B9%E7%9B%AE%E5%90%AF%E5%8A%A8%E8%87%AA%E5%8A%A8%E9%85%8D%E7%BD%AE%E9%99%90%E6%B5%81%E8%A7%84%E5%88%99 "2.项目启动自动配置限流规则")2.项目启动自动配置限流规则

常量类:

| ```
1 2 3 4 5 
``` | ```
public interface SentinelConstant {      //限流名称     String GETORDER_KEY = "getOrder"; } 
``` |
| ------------------ | ------------------------------------------------------------------------------------------------ |

SentinelInit:

| ```
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 
``` | ```
@Component public class SentinelInit implements ApplicationRunner {      @Override     public void run(ApplicationArguments args) throws Exception {         List<FlowRule> rules = new ArrayList<FlowRule>();         FlowRule rule1 = new FlowRule();         rule1.setResource(SentinelConstant.GETORDER_KEY);         // QPS控制在2以内         rule1.setCount(1);         // QPS限流         rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);         rule1.setLimitApp("default");         rules.add(rule1);         FlowRuleManager.loadRules(rules);         System.out.println("...限流配置初始化成功..");     } } 
``` |
| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

#### [](#3%E3%80%81%E9%9D%9E%E6%B3%A8%E8%A7%A3%E5%BD%A2%E5%BC%8F%E9%85%8D%E7%BD%AE%E5%88%B0%E6%8E%A5%E5%8F%A3 "3、非注解形式配置到接口")3、非注解形式配置到接口

| ```
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 
``` | ```
@RequestMapping("/getOrder")    public String getOrders() {        Entry entry = null;        try {            entry = SphU.entry(SentinelConstant.GETORDER_KEY);            // 执行我们服务需要保护的业务逻辑            return "getOrder接口";        } catch (Exception e) {            e.printStackTrace();            return "该服务接口已经达到上线!";        } finally {            // SphU.entry(xxx) 需要与 entry.exit() 成对出现,否则会导致调用链记录异常            if (entry != null) {                entry.exit();            }        }    } 
``` |
| -------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

#### [](#4%E3%80%81%E6%B3%A8%E8%A7%A3%E5%BD%A2%E5%BC%8F%E9%85%8D%E7%BD%AE%E5%88%B0%E6%8E%A5%E5%8F%A3 "4、注解形式配置到接口")4、注解形式配置到接口

| ```
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 
``` | ```
/**  * fallback 服务降级执行本地方法  * blockHandler 限流/熔断出现异常执行的方法  * value 指定我们的资源名称  * @return  */ @RequestMapping("/orderTinner") @SentinelResource(value = SentinelConstant.GETORDER_KEY,blockHandler = "getorderQpsException") public String orderTinner() {     return "orderTinner"; }  public String getorderQpsException(BlockException e){     e.printStackTrace();     return "该接口已经被限流了!!!!"; } 
``` |
| ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

### [](#%E5%9B%9B%E3%80%81%E6%8E%A7%E5%88%B6%E5%8F%B0sentinel "四、控制台sentinel")四、控制台sentinel

#### [](#1-%E4%B8%8B%E8%BD%BDjar%E5%8C%85 "1.下载jar包")1.下载jar包

参考官网

#### [](#2-%E8%BF%90%E8%A1%8C%E5%91%BD%E4%BB%A4 "2.运行命令")2.运行命令

| ```
1 
``` | ```
java -Dserver.port=8718 -Dcsp.sentinel.dashboard.server=localhost:8718 -Dproject.name=sentinel-dashboard -Dcsp.sentinel.api.port=8719 -jar /Users/jinping/Desktop/sentinel-dashboard-1.7.2.jar 
``` |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

8718属于 界面端口号 8719 属于api通讯的端口号

#### [](#%E4%BA%94%E3%80%81SpringBoot%E6%95%B4%E5%90%88Sentinel%E4%BB%AA%E8%A1%A8%E7%9B%98-%E9%85%8D%E7%BD%AE "五、SpringBoot整合Sentinel仪表盘 配置")五、SpringBoot整合Sentinel仪表盘 配置

##### [](#%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6 "配置文件")配置文件

| ```
1 2 3 4 5 6 7 8 9 10 11 12 13 14 
``` | ```
spring:   application:     name: tinner-member   cloud:     nacos:       discovery:         #nacos注册地址         server-addr: 127.0.0.1:8848     sentinel:       transport:         dashboard: 127.0.0.1:8718       eager: true server:   port: 8082 
``` |
| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

##### [](#%E5%9F%BA%E4%BA%8E%E5%B9%B6%E5%8F%91%E6%95%B0%E9%87%8F%E5%A4%84%E7%90%86%E9%99%90%E6%B5%81 "基于并发数量处理限流")基于并发数量处理限流

![基于并发数量处理限流](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4e08def160d1461b9a6b86e48e03d218~tplv-k3u1fbpfcp-zoom-1.image)

\
每次最多只会有一个线程处理该业务逻辑,超出该阈值的情况下,直接拒绝访问

##### [](#%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81 "测试代码")测试代码

| ```
1 2 3 4 5 6 7 8 9 10 11 
``` | ```
@SentinelResource(value = "getOrderThrad", blockHandler = "getOrderQpsException") @RequestMapping("/getOrderThrad") public String getOrderThrad() {     System.out.println(Thread.currentThread().getName());     try {         Thread.sleep(1000);     } catch (Exception e) {      }     return "getOrderThrad"; } 
``` |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

### [](#%E5%85%AD%E3%80%81Sentinel%E5%A6%82%E4%BD%95%E4%BF%9D%E8%AF%81%E8%A7%84%E5%88%99%E7%9A%84%E6%8C%81%E4%B9%85%E5%8C%96 "六、Sentinel如何保证规则的持久化")六、Sentinel如何保证规则的持久化

默认的情况下Sentinel的规则是存放在内存中,如果Sentinel客户端重启后,Sentinel数据规则可能会丢失。\
解决方案:**Sentinel持久化机制支持四种持久化的机制。**

* 1.本地文件

* 2.携程阿波罗

* 3.Nacos

* 4.Zookeeper

  ![数据持久化](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/347850f22cce476a9247afbb77d5e444~tplv-k3u1fbpfcp-zoom-1.image)

  ![数据持久化2](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/db6e6a63cb4c490fa8b14e92a63ccfb4~tplv-k3u1fbpfcp-zoom-1.image)