SpringCloud Alibaba微服务实战三 限流熔断

目录

简介

基础准备

安装配置

开启端口

 引入Sentinel

自定义资源@SentinelResource

 在Account配置文件中添加sentinel的服务端地址

测试

添加限流

sentniel持久化限流规则

添加降级

配置隔离


简介

Sentinel是面向分布式服务框架的轻量级流量控制框架,主要以流量为切入点,从流量控制,熔断降级,系统负载保护等多个维度来维护系统的稳定性。 在SpringCloud体系中,Sentinel主要是为了替换原Hystrix的功能,与Hystrix相比,Sentinel的隔离级别更加精细,提供的Dashboard可以在线更改限流熔断规则,而且使用也越加方便。要了解更多详细信息请移步至Sentinel官网

基础准备

安装配置

使用docker安装sentinel 1.8.0

docker pull bladex/sentinel-dashboard:1.8.0

更改配置文件

  复制到docker-compose.yaml 与 mysql nacos 同级别

  sentinel:
    image: bladex/sentinel-dashboard:1.8.0
    container_name: sentinel
    ports:
      - "8858:8858"
    restart: always
//启动sentinel
docker-compose up -d sentinel

开启端口

云服务器:开启8858 配置规则

虚拟机

// 开启端口
firewall-cmd --zone=public --add-port=8858/tcp --permanent

// 重启防火墙
firewall-cmd --reload

测试访问

账号密码:sentinel

 引入Sentinel

 在需要配置限流熔断服务的POM文件中引入Sentinel组件

 这里我们对账户服务进行限流

<!--添加sentinel-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

自定义资源@SentinelResource

我们只需要在相关方法上加上@SentinelResource注解,让其可以成为sentinel识别的资源即可。

    @SentinelResource(value = "getAccountByUserId")
    @GetMapping("/getAccountByUserId/{id}")
    public Result getAccountByUserId(@PathVariable("id")Integer id){
        LambdaQueryWrapper<Account> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Account::getId,id);
        Account account = accountService.getOne(wrapper);
        if(account==null)
        {
            throw new BusinessException(ResultCode.USER_ACCOUNT_NOT_EXIST.getCode(),
                    ResultCode.USER_ACCOUNT_NOT_EXIST.getMessage());
        }
        return Result.ok().data("account",account).data("port",port);
    }

 在Account配置文件中添加sentinel的服务端地址

    sentinel:
      transport:
        port: 8719
        dashboard: localhost:8858 # sentinel的控制台
        clientIp: localhost
      eager: true # 取消延迟加载
      enabled: true

 使用服务器需要操作下面这一步  虚拟机的可以直接跳过这一段进行测试

 下载 sentinel-dashboard-1.8.0.jar

 在放置的文件夹上cmd 运行下面这段话

java -jar -Dserver.port=8858  sentinel-dashboard-1.8.0.jar

测试

  Sentinel控制台查看

 如果没有多刷新访问几次 会有延迟

 

添加限流

 反复刷新访问出现 500说明成功 

 

对页面进行处理

    @SentinelResource(value = "getAccountByUserId",blockHandler = "flowHandler")
    @GetMapping("/getAccountByUserId/{id}")
    public Result getAccountByUserId(@PathVariable("id")Integer id){
        LambdaQueryWrapper<Account> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Account::getId,id);
        Account account = accountService.getOne(wrapper);
        if(account==null)
        {
            throw new BusinessException(ResultCode.USER_ACCOUNT_NOT_EXIST.getCode(),
                    ResultCode.USER_ACCOUNT_NOT_EXIST.getMessage());
        }
        return Result.ok().data("account",account).data("port",port);
    }
    
    //自定义异常策略
    //返回值和参数要跟目标函数一样,参数可以追加BLockException
    public Result flowHandler(@PathVariable("id")Integer id,BlockException e){
        //虽然在这里这些参数看似毫无意义,但是在实战中,这些参数我们可以存入到消息队列
        //配合消息队列或者数据库对失败的操作进行一个手动处理
        e.printStackTrace();
        return Result.error().message("访问过于频繁,请稍后重试");
    }


 重启服务需要重新添加流控

 

sentniel持久化限流规则

每次重启都需要重新添加限流 很麻烦,所以需要进行持久化来解决这个问题

account-service pom.xml引入依赖

    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-datasource-nacos</artifactId>
        <version>1.8.0</version>
    </dependency>

yaml

    sentinel:
      eager: true # 取消延迟加载
      transport:
        port: 8719
        dashboard: localhost:8858 # sentinel的控制台
        clientIp: localhost
      datasource:
        ds:
          nacos:
            server-addr: 106.55.10.118:8848   #nacos的服务注册中心
            group-id: DEFAULT_GROUP           #nacos配置中心的组id
            data-id: account-sentinel.json    #这是唯一的数据id
            rule-type: flow                   #规则为限流

 nacos添加配置

[
    {
        "resource": "getAccountByUserId",
        "limitApp": "default",
        "grade": 1,
        "count": 3,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    }
]

 nacos添加后重启服务 可查看流控的存在

 

添加降级

假设我们访问了5次但是又两次是超时的,40%=0.4

这个时候会触发熔断机制,熔断时间表示我们在这个熔断的时间内,不管怎么访问都是返回的熔断处理

 

 熔断一般是出现了异常,或者访问资源超时,都会触发熔断机制

这个不好演示 直接抛出异常

    @SentinelResource(value = "getAccountByUserId",blockHandler = "flowHandler",
    fallback= "fallbackHandler")
    @GetMapping("/getAccountByUserId/{id}")
    public Result getAccountByUserId(@PathVariable("id")Integer id){
        LambdaQueryWrapper<Account> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Account::getId,id);
        Account account = accountService.getOne(wrapper);
        if(account==null)
        {
            throw new BusinessException(ResultCode.USER_ACCOUNT_NOT_EXIST.getCode(),
                    ResultCode.USER_ACCOUNT_NOT_EXIST.getMessage());
        }
        //return Result.ok().data("account",account).data("port",port);
        throw  new RuntimeException("error");
    }


    //自定义异常策略
    //返回值和参数要跟目标函数一样,参数可以追加BLockException
    public Result flowHandler(@PathVariable("id")Integer id,BlockException e){
        //虽然在这里这些参数看似毫无意义,但是在实战中,这些参数我们可以存入到消息队列
        //配合消息队列或者数据库对失败的操作进行一个手动处理
        e.printStackTrace();
        return Result.error().message("访问过于频繁,请稍后重试");
    }

    public Result fallbackHandler(@PathVariable("id") Integer id){
        return Result.error().message("触发了熔断机制");
    }

 测试

 

 配置隔离

 引入配置中心组件spring-cloud-starter-alibaba-nacos-config

    <!--nacos的配置中心-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>

    <!--2020/2021的SpringCloud才需要引入这个,不然无法读取Bootstrap.yaml文件-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bootstrap</artifactId>
    </dependency>

nacos新建命名空间

 在account下新建配置

 将application.yaml内容 复制过来

 删除 application.yaml

 创建 bootstrap.yaml

spring:
  application:
    name: account_service
  cloud:
    nacos:
      config:
        server-addr: 192.55.10.118:8848
        file-extension: yaml
        group: DEFAULT_GROUP
        namespace: 51590662-b609-44b5-b834-e7042a73a9c9

namespace 是tenant_id字段

重启测试成功即可!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值