99-java-springcloud(12)-cloudalibaba(02)-熔断与限流-sentinel

sentinel

在这里插入图片描述

一.概述

1.介绍及简介
(1) 官网

官网地址: https://github.com/alibaba/Sentinel
中文文档: https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D
spring-alibaba-sentinel 地址:
https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html#_spring_cloud_alibaba_sentinel

(2) sentinel是什么?

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

(3) sentinel有什么特点?
  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10
    年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500
    台以下规模的集群的汇总运行情况。
  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC
    的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
  • 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI
    扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
    在这里插入图片描述
(4) 解决微服务调用的问题
  • 服务降级
    当微服务之间调用出现错误,或者超时,则怎么处理结果,保护服务不发生雪崩效应.
  • 服务熔断
    当微服务之间的调用发生的错误次数过多时,为了避免多次的错误调用,提供服务的稳定性,是服务调用发生服务熔断效果,并且在一定的时间窗口期可以重新尝试恢复服务调用.
  • 服务限流
    当高并发,大流量时,保证服务的稳定性,不受大量请求的冲击而采用服务限流策略.
2.下载及安装

sentinel也是采用的server+client模式:
在这里插入图片描述

说明:
server端作为服务监控,平台,提供监控功能.
server端作为服务降级,熔断,流控等配置平台,可配置相关信息.
client端连接server端.

(1) 下载

下载地址: https://github.com/alibaba/Sentinel/releases
在这里插入图片描述

(2) 解压并运行

在这里插入图片描述

(3) 检查是否安装成功

登陆控制台: localhost:8080
登录账号密码均为sentinel
在这里插入图片描述
控制台首页:
在这里插入图片描述

二.功能演示

1.搭建基础项目
  1. 建module
  2. 改pom
    因为我们本module的设计的注册中心是nacos,所以添加了nacos的依赖和sentinel的依赖
		<!--nacos的注册中心-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--sentinel服务熔断-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
  1. 写yml
server:
  port: 8401

spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos: #nacos的server端地址
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
        dashboard: localhost:8080 #监控面板的server端地址
        port: 8719  #默认8719,假如被占用了会自动从8719开始依次+1扫描。直至找到未被占用的端口

management:
  endpoints:
    web:
      exposure:
        include: '*'

  1. 主启动
    没有什么特别的注解代码,并不像hystrix(@EnableHystrix)一样需要添加启动注解
@EnableDiscoveryClient
@SpringBootApplication
public class MainApp8401
{
    public static void main(String[] args) {
        SpringApplication.run(MainApp8401.class, args);
    }
}
 
  1. 业务类
    添加测试业务类,用于测试sentinel功能
@RestController
public class FlowLimitController
{
    @GetMapping("/testA")
    public String testA() {
        return "------testA";
    }

    @GetMapping("/testB")
    public String testB() {

        return "------testB";
    }

}
 
  1. 测试
    (1) 依次启动nacos,sentinel,本module服务
    (2) 调用依次本服务的接口
    查看sentinel控制台显示如下,则表示监控到了,我们刚刚调用的接口服务.
    接下来,结合实际的场景解释每一个功能按钮的作用.
    在这里插入图片描述
2.流控(流量控制)

流控: 针对访问资源api接口的QPS或者是并发线程数做控制,其实也就是并发数做控制策略.
在这里插入图片描述

(1) 添加流控规则

在这里插入图片描述

(2) 流控规则介绍

在这里插入图片描述

  • 1 资源名
    表示本规则,针对的资源,也就是限制的资源路劲是哪个.

  • 2 针对来源
    是否是针对特殊来源请求的流控规则

  • 3 阈值
    流控有两方面,一个是并发数QPS(每秒访问的次数),一个是并发线程数,同一时刻访问本api的线程数.

  • 4 流控模式

    • 直接(默认): 自己的事情,自己负责.
    • 关联: 关联的资源达到阈值,则限流自己;常被用来资源限流,如果资源A调用资源B,如果资源B被限流了,则A肯定也无法调用,所以也就限流了A,这就是关联.
    • 链路: 多个请求调用了同一个微服务
  • 5 流控效果

    • 快速失败(默认): 如果本资源达到阈值,流控了,则直接响应失败,抛出异常.异常默认是flow limited.
      源码com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController
    • Warm up: 如果本资源达到阈值,流控了,则进入预热 .
      https://github.com/alibaba/Sentinel/wiki/%E9%99%90%E6%B5%81---%E5%86%B7%E5%90%AF%E5%8A%A8
      在这里插入图片描述
      公式:阈值除以coldFactor(默认值为3),经过预热时长后才会达到阈值
      在这里插入图片描述
      例如:
      在这里插入图片描述
    • 排队: 匀速排队,阈值必须设置为QPS
      在这里插入图片描述
      在这里插入图片描述
3.服务降级

服务降级: 服务降级的意思就是该资源发生错误或者超时等情况的时候,我们怎么处理错误或者超时.
在这里插入图片描述

(1) 添加降级规则

在这里插入图片描述

(2) 降级规则介绍

在这里插入图片描述

  • 资源名
    配置服务降级的资源api路劲
  • 降级策略
    什么情况下发生服务降级.
    • RT: 平均响应时间
      在这里插入图片描述
      在这里插入图片描述

    • 异常比例: 当请求达到多少QPS时,如果错误请求的占比达到多少时,发生服务降级
      在这里插入图片描述
      在这里插入图片描述

    • 异常数: 当请求达到多少QPS时,如果错误请求的数量达到多少时,发生服务降级
      在这里插入图片描述
      在这里插入图片描述

4.热点规则

热点规则: 这个控制更加的细粒度了,前面的是针对的接口api,这个是针对访问api携带某个或者某些参数值的请求做流控,可以降低热点商品对系统的冲击.
在这里插入图片描述在这里插入图片描述

(1) 热点规则测试
  • 添加一个测试的业务方法
 /**
     * 测试热点key
     * @param p1 添加了热点规则的参数p1
     * @param p2 未添加热点参数规则的p2
     * 类似于hystrix的@HystrixCommand
     *  @SentinelResource
     *      value: 资源名
     *      blockHandler: 发生热点.流控等规则的时候回调的方法名
     *      fallback: 发生超时/异常等时候调用的方法名
     */
    @SentinelResource(value = "testHotKey",blockHandler = "deal_hotKey",fallback = "fallback_method")
    @GetMapping("/testHotKey")
    public String testHotKey(@RequestParam(value = "p1",required = false) String p1,
                             @RequestParam(value = "p2",required = false) String p2){
        log.info("===========testHotKey");
        return "===========testHotKey";
    }

    /**
     *这是热点规则之后调用的方法
     */
    public String deal_hotKey(String p1, String p2, BlockedException ex){
        log.info(ex.getMessage());
        return "**************deal_hotKey";
    }

    /**
     * 这是出现runtimeException出现服务降级,调用的方法
     * @return
     */
    public String fallback_method(){
        return "**************fallback_method";
    }
  • 添加热点规则

在这里插入图片描述
在这里插入图片描述

  • 测试
    • http://localhost:8401/testHotKey?p1=abc
      带有第一个参数p1的时候,如果请求QPS超过1则被限流
    • http://localhost:8401/testHotKey?p1=abc&p2=33
      带有第一个参数p1的时候,如果请求QPS超过1则被限流
    • http://localhost:8401/testHotKey?p2=abc
      不带有第一个参数p1的时候,任意的QPS都不会被限流.

参数例外项: 表示我们对一个参数进行流控,但是当参数值等于某个数的时候,我们则使用另外的阈值限流.
在这里插入图片描述

5.系统规则

(1) 官网地址: https://github.com/alibaba/Sentinel/wiki/%E7%B3%BB%E7%BB%9F%E8%87%AA%E9%80%82%E5%BA%94%E9%99%90%E6%B5%81
(2) 官网说明
在这里插入图片描述
(3) 总之
配置全局QPS

三.@SentinelResource

@SentinelResource注解的属性说明.
在这里插入图片描述

代码说明:
RateLimitController.class

@RestController
public class RateLimitController {
    /**
     * 按照url路劲限流,限流后走系统自带的方法
     * @return
     */
    @GetMapping("/rateLimit/byUrl")
    @SentinelResource(value = "byUrl")
    public CommonResult byUrl()
    {
        return new CommonResult(200,"按url限流测试OK",new Payment(2020L,"serial002"));
    }

    /**
     * 按照资源限流,限流后走我们配置的处理方法
     * @return
     */
    @GetMapping("/byResource")
    @SentinelResource(value = "byResource", blockHandler = "handleException")
    public CommonResult byResource() {
        return new CommonResult(200, "按资源名称限流测试OK", new Payment(2020L, "serial001"));
    }

    public CommonResult handleException(BlockException exception) {
        return new CommonResult(444, exception.getClass().getCanonicalName() + "\t 服务不可用");
    }

    /**
     * 调用全局处理的限流类
     * @return
     */
    @GetMapping("/rateLimit/customerBlockHandler")
    @SentinelResource(value = "customerBlockHandler", //资源名
            blockHandlerClass = CustomerBlockHandler.class, //调用限流类
            blockHandler = "handleException2") //调用该类的哪个方法
    public CommonResult customerBlockHandler()
    {
        return new CommonResult(200,"按客戶自定义",new Payment(2020L,"serial003"));
    }
}

/**
 * @author gl
 * @time 2020-06-27 1:06
 * @function :全局限流异常处理类
 * @step :
 */
public class CustomerBlockHandler {

    /**
     * BlockException处理方法1
     * @param exception
     * @return
     */
    public static CommonResult handleException(BlockException exception) {
        return new CommonResult(2020, "自定义限流处理信息....CustomerBlockHandler");
    }


    /**
     * BlockedException 异常处理方法2
     * @param exception
     * @return
     */
    public static CommonResult handleException2(BlockedException exception)
    {
        return new CommonResult(2020,"自定义限流处理信息....handlerException2----2");
    }
}

四.sentinel整合ribbon+openFeign

1.模块搭建
  1. 建module
  2. 改pom
    添加sentinel依赖
		<!--整合feign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!--整合nacos-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--整合sentinel-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
  1. 写yml
    注意一定要开启feign对sentinel的支持.
server:
  port: 84

spring:
  application:
    name: nacos-order-consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8719

service-url:
  nacos-user-service: http://nacos-payment-provider

#对Feign的支持
feign:
  sentinel:
    enabled: true


  1. 主启动
@SpringBootApplication
@EnableDiscoveryClient //nacos的连接客户端
@EnableFeignClients //openfeign的客户端
public class OrderNacosMain84 {

     public static void main(String[] args) {
            SpringApplication.run(OrderNacosMain84.class,args);
        }
}

  1. 业务类
    (1) restTemplate + ribbon + sentinel的方式
    注入RestTemplate类.
@Configuration
public class ApplicationContextConfig {

    @Bean
    @LoadBalanced //ribbon的注解
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

业务controller类

/**
 * @author gl
 * @time 2020-06-27 23:35
 * @function : 测试sentinel配合ribbon
 * @step :
 */
@RestController
@Slf4j
public class CircleBreakerController {
    public static final String SERVICE_URL = "http://nacos-payment-provider";

    @Resource
    private RestTemplate restTemplate;

    @RequestMapping("/consumer/fallback/{id}")
    //@SentinelResource(value = "fallback") //没有配置
    //@SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只负责业务异常
    //@SentinelResource(value = "fallback",blockHandler = "blockHandler") //blockHandler只负责sentinel控制台配置违规
    @SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler",
            exceptionsToIgnore = {IllegalArgumentException.class})
    public CommonResult<Payment> fallback(@PathVariable Long id) {
        CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id, CommonResult.class, id);

        if (id == 4) {
            throw new IllegalArgumentException ("IllegalArgumentException,非法参数异常....");
        }else if (result.getData() == null) {
            throw new NullPointerException ("NullPointerException,该ID没有对应记录,空指针异常");
        }

        return result;
    }

    //fallback
    public CommonResult handlerFallback(@PathVariable Long id, Throwable e) {
        Payment payment = new Payment(id,"null");
        return new CommonResult<>(444,"兜底异常handlerFallback,exception内容  "+e.getMessage(),payment);
    }

    //blockHandler
    public CommonResult blockHandler(@PathVariable  Long id,BlockException blockException) {
        Payment payment = new Payment(id,"null");
        return new CommonResult<>(445,"blockHandler-sentinel限流,无此流水: blockException  "+blockException.getMessage(),payment);
    }

(2) feign + ribbon + sentinel的方式
feign接口类

@FeignClient(value = "nacos-payment-provider", fallback = PaymentServiceHandler.class)
public interface PaymentService {

    @GetMapping(value = "/paymentSQL/{id}")
    public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id);

}

fallback服务降级类

/**
 * @author gl
 * @time 2020-06-28 0:05
 * @function : fallback服务降级类
 * @step :
 */
@Component
public class PaymentServiceHandler implements PaymentService{
    @Override
    public CommonResult<Payment> paymentSQL(Long id) {
        return new CommonResult<>(4444,"服务降级!!");
    }
}

五.服务降级/熔断框架比较

在这里插入图片描述
在这里插入图片描述

六.服务规则持久化

1.是什么?

一旦我们重启应用,Sentinel规则将消失,生产环境需要将配置规则进行持久化

2.怎么玩?

(1) 说明
将限流配置规则持久化进Nacos保存,只要刷新8401某个rest地址,sentinel就能从nacos读取配置文件作为规则文件,然后只要刷新8401某个rest地址,就能读取规则文件.

(2) 步骤

  1. 添加pom依赖
<dependency>
    <groupId>com.alibaba.csp</groupId>
	    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
  1. 修改yml
spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848  #注册到nacos的地址
    sentinel:
      transport:
        dashboard: localhost:8080  #sentinel的dashboard的位置
        port: 8719  #默认8719,假如被占用了会自动从8719开始依次+1扫描。直至找到未被占用的端口
      datasource:  #sentinel的持久化,默认读取nacos(localhost:8848)中的这个文件(cloudalibaba-sentinel-service),这个文件是json格式的
        ds1:
          nacos: #sentinel规则持久化到nacos的配置文件信息中
            server-addr: localhost:8848 #nacos的地址
            dataId: cloudalibaba-sentinel-service  #文件名
            groupId: DEFAULT_GROUP  #分组
            data-type: json #数据格式
            rule-type: flow
  1. 在nacos中添加sentinel的持久化文件
    在这里插入图片描述
    在这里插入图片描述

  2. 测试
    重启sentinel的微服务该项目,刷新查看是否读取到nacos中的规则文件
    在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud Alibaba Sentinel是一个基于Java的开源框架,提供了熔断、降级、限流、系统负载保护等功能,可以帮助开发者实现微服务架构中的高可用性和稳定性。下面是一个使用Spring Cloud Alibaba Sentinel实现熔断限流的项目介绍。 1. 创建Spring Boot项目 首先,需要创建一个Spring Boot项目,并添加Spring Cloud Alibaba Sentinel的依赖: ```xml <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>2.2.3.RELEASE</version> </dependency> ``` 2. 配置Sentinel Dashboard Sentinel Dashboard是Sentinel的可视化管理平台,可以通过它来查看应用程序的运行状况、配置规则等。需要在项目中添加Sentinel Dashboard的依赖: ```xml <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel-datasource-nacos</artifactId> <version>2.2.3.RELEASE</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-sentinel-dashboard</artifactId> <version>2.1.1.RELEASE</version> </dependency> ``` 同时,在application.properties文件中添加以下配置: ```properties # Sentinel Dashboard配置 spring.cloud.sentinel.transport.dashboard=localhost:8080 # Nacos配置 spring.cloud.nacos.discovery.server-addr=localhost:8848 spring.cloud.nacos.discovery.namespace= spring.cloud.nacos.discovery.username= spring.cloud.nacos.discovery.password= ``` 启动项目后,访问http://localhost:8080即可进入Sentinel Dashboard界面。 3. 实现熔断限流 在项目中可以通过注解方式实现熔断限流功能。例如,在Controller类中添加以下代码: ```java @RestController public class HelloController { @GetMapping("/hello") @SentinelResource(value = "hello", fallback = "fallback") public String hello(@RequestParam(required = false) String name) { if(StringUtils.isEmpty(name)) { throw new IllegalArgumentException("name is empty"); } return "Hello, " + name; } public String fallback(String name) { return "fallback " + name; } } ``` @SentinelResource注解指定了资源名称为hello,同时指定了fallback方法用于处理熔断降级。可以通过Sentinel Dashboard配置熔断规则和流量控制规则。 以上就是使用Spring Cloud Alibaba Sentinel实现熔断限流的项目介绍。使用Sentinel可以帮助我们更好地保障应用程序的稳定性和可用性,避免因为异常情况导致系统崩溃。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值