1.简介

现在微服务的流行,一个稳定的服务调用越发重要,sentinel使用流量作为突破点,对为服务进行监控、熔断和负载保护

  • 丰富的使用场景:双11
  • 实时监控
  • 开源
  • 快速扩展

    2.实例Demo

    2.1sentinel控制台的安装

  1. 下载软件包
  2. 命令启动(若8080被占用可以使用 其他端口 替换)

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

    3.控制台访问:http://localhost:8089
    4.登录名和密码都是 : sentinel

    2.2微服务的搭建

  3. pom

    1. <dependency>
    2. <groupId>com.alibaba.cloud</groupId>
    3. <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    4. </dependency>
  4. 编写一个Controller

    1. @RestController
    2. public class SentinalController {
    3. @RequestMapping("sayHello")
    4. public String sayHello(){
    5. return "hello World";
    6. }
    7. }
  5. 配置文件(因为我控制台用 8089端口启动的)

    1. spring:
    2. cloud:
    3. sentinel:
    4. transport:
    5. port: 8719
    6. dashboard: localhost:8089

    8719端口解释:在使用sentinel时,每个整合了sentinel的微服务需要和sentinel控制中心通信,于是需要再次启动一个HTTP服务器来和控制中心通信,获取流量控制的配置信息,于是8719就是指名这个http服务器的端口,若端口被占用,会自增

    2.3查看控制台

  6. 服务中的资源(接口)被调用过一次后,才会被触发监控

  7. 对于一些@RequestMapping之类的接口,http服务提供了限流埋点
  8. 但是对于一些普通的方法,比如:

    1. @RestController
    2. public class SentinalController {
    3. @RequestMapping("sayHello")
    4. public String sayHello(){
    5. cleanMySelf();
    6. return "hello World";
    7. }
    8. public String cleanMySelf(){
    9. return "cleanMySelf";
    10. }
    11. }

    在sayHello前要cleanMySelf(),这个方法不能被控制,在控制台上只有sayHello
    image.png
    4.解决上述 第3点的策略就是在方法上 添加 @SenttinalResource(后面咱们单独一章讲)

    1. @RestController
    2. public class SentinalController {
    3. @RequestMapping("sayHello")
    4. public String sayHello(){
    5. cleanMySelf();
    6. return "hello World";
    7. }
    8. @SentinelResource("cleanMySelf")
    9. public String cleanMySelf(){
    10. return "cleanMySelf";
    11. }
    12. }

    这里发现,还是不行,这个错误要保留一下,因为他底层使用AOP方式实现,所以改动一些将cleanMySelf移入Service层
    5.代码如下:

    1. @Service
    2. public class SentinelService {
    3. @SentinelResource("cleanMySelf")
    4. public String cleanMySelf(){
    5. return "cleanMySelf";
    6. }
    7. }
    1. @RestController
    2. public class SentinalController {
    3. @Autowired
    4. private SentinelService sentinelService;
    5. @RequestMapping("sayHello")
    6. public String sayHello(){
    7. sentinelService.cleanMySelf();
    8. return "hello World";
    9. }
    10. }

    3.规则配置

    规则配置的话,可以使用控制台,也可以使用代码的方式。我这里只整理控制台的形式
    image.png
    可以看到有流控、降级、热点和授权四个按钮,咱们就讲讲如何配置这4个

    3.1流控的配置

  9. 名词解释

    1. QPS:query per second(每秒请求数)
  10. 基础配置

image.png

  1. QPS、单机阈值3:每秒的请求超过3次就返回错误提示,(线程数一样)

image.png
b.点击集群后,可以设置均摊的阈值或总体阈值
image.png

  1. 高级选项中的配置

image.png
4.流控模式
这里先解释一个来源的概念:就是我这个服务的调用者。

  1. 直接模式:当针对来源直接的调用,才记录到QPS中
  2. 关联:需要指明sentinel中的另一资源名称,也就是说我两者的QPS之和不能超过这个阈值
  3. 链路:资源C可能,资源A要用,资源B要用,可以只对资源A使用它的量限制,

5.流控效果

  1. 快速失败:达到流控条件后,立刻返回 flow control
  2. warm up :我设置了一个阈值,但是刚开始,我的QPS阈值小于这个值,经过一段时间后才真正成为这个阈值
  3. 排队等待:当达到阈值后,又进来的请求不立即返回失败,而是在队列等待指定时间

    3.2降级配置

    image.png
    1.RT:1s中5次以上的请求,求平均响应时间,若大于100ms,则熔断2s
    image.png
    2.异常比例:1s中5次以上请求,异常比例超过 1=100%,就在5s能返回降级
    3.异常数:1分钟内请求的异常数超过阈值,降级 指定时间

    3.3热点参数限流

    image.png

  4. 就是对资源中的某个参数请求,进行限制

  5. 对这个参数的具体某些值也可以特定限制
  6. 踩坑:首先这样的资源必须加@SentinelResources注解

一定要在下图的资源上设置,不要再/*上面设置
image.png
4.当达到限制条件时,返回的是错误页面,需要在注解上添加 fallback方法(后面再说)

3.4授权

image.png
源应该指的是 服务调服务中的源

4.对OpenFeign的支持

  1. 就是将histrix的换成 sentinel
  2. 配置如下:

    1. feign:
    2. sentinel:
    3. enabled: true

    5.对GateWay的支持

  3. pom

    1. <dependency>
    2. <groupId>org.springframework.cloud</groupId>
    3. <artifactId>spring-cloud-starter-gateway</artifactId>
    4. </dependency>
    5. <dependency>
    6. <groupId>com.alibaba.cloud</groupId>
    7. <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    8. </dependency>
    9. <dependency>
    10. <groupId>com.alibaba.cloud</groupId>
    11. <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    12. </dependency>
    13. <dependency>
    14. <groupId>com.alibaba.cloud</groupId>
    15. <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
    16. </dependency>
  4. 配置文件 ```yaml server: port: 10000 spring: application: name: cloud-gateway cloud: nacos: discovery:

    1. server-addr: 127.0.0.1:8848

    gateway: routes:

    • id: hello-service uri: lb://hello-service predicates:
      • Path=/hello-service/** filters:
      • StripPrefix=1 discovery: locator: lower-case-service-id: true enabled: true sentinel: transport: dashboard: localhost:8089 scg: fallback: mode: response response-body: fallBackHello response-status: 444
  1. 3. 流控配置
  2. - RouteID ,就是配置中的 -id hello-service ,就是这个服务的所有接口都流控
  3. - API分组,就是进行请求地址的正则匹配,进行流控
  4. 4. 2022.4.4号小坑记录
  5. - spring-boot2.2.9.RELEASE
  6. - spring-cloudHoxton.SR3
  7. - spring-cloud-alibaba2.2.1.RELEASE
  8. > 问题:网关流控无效
  9. > 结果:与sentinel的控制台无关1.8.3。要指定好版本
  10. ```powershell
  11. <dependency>
  12. <groupId>org.springframework.cloud</groupId>
  13. <artifactId>spring-cloud-starter-gateway</artifactId>
  14. <version>2.2.0.RELEASE</version>
  15. </dependency>
  16. <dependency>
  17. <groupId>com.alibaba.cloud</groupId>
  18. <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
  19. <version>2.2.0.RELEASE</version>
  20. </dependency>
  21. <dependency>
  22. <groupId>com.alibaba.cloud</groupId>
  23. <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
  24. <version>2.2.1.RELEASE</version>
  25. </dependency>
  1. 配制实例

    image.png

  2. 解释

①需要为你的数据源取一个响亮的名字9(ds1/ds2/…..只要你喜欢,随便你定义)
②配置所在的位置:file、nacos、zookeeper、appollo(这个必须一定的)

  1. 每一个数据源所需要配置3个配置项

①data-type:数据类型(json、xml、custom自定义)
②converter-class:将数据类型转化的转化器(默认就是 xml、json,或者你自己定义一个)
③rule-type:(flowdegradeauthoritysystem, param-flow, gw-flow, gw-api-group
image.png
④建议使用json(默认的转换器、默认的数据类型)

  1. 定义流控、降级等规则的方式
    1. 通过写代码的形式定义(不灵活、换个规则就得重写代码)
    2. 通过控制台配置、直观、明了但是不可持久,于是需要一个存储数据的地方
  2. 从数据源中如何获取
    1. 数据源推送给客户端:nacos redis zk等
    2. 客户端主动去要:文件
  3. 演示一把从 nacos 中配置规则
    1. push模式的原理图

image.png

  1. 配置实例(springcloudalibaba 的 example中有例子怎么配,各种配置文件怎么写,去看)

①pom文件

  1. <dependency>
  2. <groupId>com.alibaba.cloud</groupId>
  3. <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>com.alibaba.cloud</groupId>
  7. <artifactId>spring-cloud-alibaba-sentinel-datasource</artifactId>
  8. </dependency>
  9. <dependency>
  10. <groupId>com.alibaba.csp</groupId>
  11. <artifactId>sentinel-datasource-nacos</artifactId>
  12. </dependency>

②配置

  1. spring:
  2. cloud:
  3. sentinel:
  4. transport:
  5. port: 8719
  6. dashboard: localhost:8089
  7. datasource:
  8. ds1:
  9. nacos:
  10. server-addr: localhost:8848
  11. data-id: sentinel
  12. group-id: DEFAULT_GROUP
  13. data-type: json
  14. rule-type: flow
  1. 2022/4/4号吐槽

    • 官方文档给了我们这种通过文件去配置的功能,但是文件配置到底怎么写?为啥不告诉
    • 具体文件写法这边还是通过看SpringCloudAlibaba提供的example来学习的
    • nacos配置文件->sentinel控制台在官网上勉强找到地方学到了,那sentinel控制台->nacos怎么搞(只能搜博客)?

      7.@SentinelResource注解

  2. 定义资源名称使用

  3. 指定流控的规则(默认的流控规则太丑)

image.png

  1. 总体自定义流控规则 ```java public class CustomUrlBlockHandler implements UrlBlockHandler { @Override public void blocked(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws IOException {
    1. httpServletResponse.setStatus(436);
    2. httpServletResponse.setCharacterEncoding("UTF-8");
    3. httpServletResponse.getWriter().println("流控限制");
    } }

@Configuration public class MyConfig { @Bean public WebCallbackManager webCallbackManager(){ WebCallbackManager.setUrlBlockHandler(new CustomUrlBlockHandler()); return new WebCallbackManager(); } }

  1. 4. 通过注解指定(blockHandler
  2. blockHandlerClass:指定的产生的处理方法`blockHandler`在那个类<br />blockHandler:指定具体那个方法<br />注意点:<br />①若只使用blockHandler,方法必须和流控资源在同一类,参数、返回值一致,并且在最后参数添加BlockException<br />②若使用class+handler的方式,还需要 方法为static
  3. 5. fallBackfallBackClass
  4. 同上面用法一样,但是不同的是,这个方法是针对所有抛出来的异常
  5. ```java
  6. @RequestMapping("testFallBack")
  7. @SentinelResource(value="testFallBack",fallback = "doFallBack")
  8. public String testFallBack(){
  9. int a=1/0;
  10. return "hello";
  11. }
  12. public String doFallBack(Throwable throwable){
  13. System.out.println(throwable.getStackTrace());
  14. return throwable.getMessage();
  15. }

6.defaultFallback:就是没指定fallback的情况下走它
7.exceptionToIgnore:翻译一下。