SpringCloud-整体学习(十一) Sentinel(服务降级)

SpringCloud-整体学习(一)SpringCloud简介+版本选择
SpringCloud-整体学习(二)项目初始构建-加公共部分提取
SpringCloud-整体学习(三)Eureka、zookeeper、Consul(注册中心)
SpringCloud-整体学习(四)Ribbon(负载均衡+手写轮询算法)
SpringCloud-整体学习(五)OpenFeign(服务调用)
SpringCloud-整体学习(六)Hystrix(服务降级)
SpringCloud-整体学习(七)GateWay(服务网关)
SpringCloud-整体学习(八)Config、Bus、Stream(服务配置和消息交互)
SpringCloud-整体学习(九)Sleuth(分布式请求链路追踪)
SpringCloud-整体学习(十)SpringCloudAlibaba(注册中心+配置中心)
SpringCloud-整体学习(十一) Sentinel(服务降级)
SpringCloud-整体学习(十二) Seata(分布式事务)

git :
https://github.com/lucine-maker/cloud2020
gitee:
https://gitee.com/lucine_li_tao/springcloud

Sentinel文档地址:
https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D

Sentinel是什么

https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D

Sentinel下载安装运行

下载慢得多可以去码云上下载源码然后
mvn package -Dmaven.text.skip=true
在这里插入图片描述
https://gitee.com/mirrors/Sentinel/tree/1.7.0/
然后就拿到了jar
java -jar xxxx.jar
账号密码都是sentinel
在这里插入图片描述

Sentinel初始化监控

1、启动nacos --8848
2、新建cloudalibaba-sentinel-service8401
3、启动Sentinel8080
最后让8401注册进去nacos,然后在Sentinel保护启动的服务

2、新建:
pom

<dependencies>
        <!-- SpringCloud ailibaba nacos-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- SpringCloud ailibaba sentinel-datasource-nacos 持久化需要用到-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>
        <!-- SpringCloud ailibaba sentinel-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <dependency>
            <groupId>com.lt.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--监控-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

yml:

server:
  port: 8401
spring:
  application:
    name: cloudalibaba-sentinal-service
  cloud:
    nacos:
      discovery:
        #Nacos服务注册中心地址
        server-addr: localhost:8848
    sentinel:
      transport:
        #配置Sentinel dashboard地址
        dashboard: localhost:8080
        # 默认8719端口,假如被占用了会自动从8719端口+1进行扫描,直到找到未被占用的 端口
        port: 8719
management:
  endpoints:
    web:
      exposure:
        include: '*'

controller 和主启动都比较简单
在这里插入图片描述

第一次sentinel本身是懒加载只有请求一次后,就会加载进去
http://localhost:8401/testA
在这里插入图片描述

Sentinel流控-QPS直接失败

QPS 是每秒点击数
单机阈值数只要超过就报错。(快速失败情况下)
在这里插入图片描述

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

Sentinel流控-线程数直接失败

线程就不多解释了。

Sentinel流控-关联

b如果出了问题,A就限流自己(例如支付服务挂了,限流下订单的服务)
在这里插入图片描述

在这里插入图片描述

Sentinel流控-链路

https://www.it610.com/article/1294223962267525120.htm
这个文章中的链路流控讲的比较易懂写

Sentinel流控-预热

https://github.com/alibaba/Sentinel/wiki/%E9%99%90%E6%B5%81—%E5%86%B7%E5%90%AF%E5%8A%A8

如果设置阈值为10,并不是上来就是10,而是慢慢的到达10。
默认 coldFactor 为 3,即请求 QPS 从 threshold / 3 开始,经预热时长逐渐升至设定的 QPS 阈值。

在这里插入图片描述

在这里插入图片描述

Sentinel流控-排队等待

https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6-%E5%8C%80%E9%80%9F%E6%8E%92%E9%98%9F%E6%A8%A1%E5%BC%8F
在这里插入图片描述

Sentinel降级简介

https://github.com/alibaba/Sentinel/wiki/%E7%86%94%E6%96%AD%E9%99%8D%E7%BA%A7

Sentinel降级-RT

1、在未来的时间窗口(1s)中如果你200ms没有完成
2、在未来的时间窗口(1s)中线程数访问超过了设置的值(默认5),
一句话:一秒之内5个线程在200ms没有完成
1和2 都满足 就在后面所有的窗口期中都触发降级
在这里插入图片描述

Sentinel降级-异常比例、异常数

时间窗口期中,且请求线程数大于5:
成功次数/请求次数大于设置的比例就成功
异常数大于设置的值
在这里插入图片描述

Sentinel热点key(上)

https://github.com/alibaba/Sentinel/wiki/%E7%83%AD%E7%82%B9%E5%8F%82%E6%95%B0%E9%99%90%E6%B5%81

在controller中

@GetMapping("/testHotKey")
    @SentinelResource(value = "testHotKey", blockHandler ="deal_testHotKey")
    public String testHotKey(@RequestParam(value = "p1",required = false) String p1,
                             @RequestParam(value ="p2",required = false) String p2){
        return "testHotKey 返回";
    }

    public String deal_testHotKey(String p1, String p2, BlockException e){
        return "deal_testHotKey 返回";
    }

在这里插入图片描述

@SentinelResource 注解中的value 为唯一标识资源名
blockHandler 为触发限流后触发的方法(不包括本身程序发生的错误)
sentinel中的参数索引 对方法入参的单个参数限制 是从0依次数

Sentinel热点key(下)

参数例外项可以让参数在特殊的值得时候不同的限流规则
写完记得点后面的添加。

在这里插入图片描述
上面是反例 :我的类型写错了,没有生效

Sentinel系统规则

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

之前做的是单个方法的限制,这个是全局的系统的限制(调小了可能会导致整个系统不可用)
在这里插入图片描述

在这里插入图片描述

SentinelResource配置

新建Controller

@RestController
public class RateLimitController {

    @GetMapping("/byResource")
    @SentinelResource(value = "byResource")
    public CommonResult testHotKey(){
        return new CommonResult(200,"按资源名称限流测试ok",new Payment(2020L,"serial001"));
    }

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

    @GetMapping("/testMyhandler")
    @SentinelResource(value = "testMyhandleraa",
            blockHandlerClass = CustomerBlockHandler.class,
            blockHandler ="handleException2")
    public CommonResult testMyhandler(){
        return new CommonResult(200,"按资源名称限流测试ok",new Payment(2020L,"serial001"));
    }
}

@GetMapping 和 @SentinelResource 中的值不要一致(否则可能会一直走自定义异常)

目前的问题和之前的Hystrix 面临的问题差不多需要解耦

新建CustomerBlockHandler(为异常做统一处理):
在这里插入图片描述

public class CustomerBlockHandler {

	public static CommonResult handleException(BlockException exception){
        return new CommonResult(4444,"自定义的异常4444----1");
    }

    public static CommonResult handleException2(BlockException exception){
        return new CommonResult(4444,"自定义的异常4444----2");
    }

}

在这里插入图片描述

在这里插入图片描述

Sentinel服务熔断Ribbon环境预说

搭建
在这里插入图片描述

9003和9004只是端口不一致
pom不在记录
yml

server:
  port: 9004


spring:
  application:
    name: nacos-payment-provider
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

management:
  endpoints:
    web:
      exposure:
        exclude: '*'

9003、4controller

@Value("${server.port}")
    private  String serverPort;

    public static HashMap<Long, Payment> map = new HashMap<>();
    static {
        map.put(1L,new Payment(1L,"1111"));
        map.put(2L,new Payment(2L,"2222"));
        map.put(3L,new Payment(3L,"3333"));
    }


    @GetMapping(value = "/paymentSQL/{id}")
    public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id) {
        Payment payment = map.get(id);
        CommonResult<Payment> result = new CommonResult<>(200,"from mysql,serverPort: " + serverPort,payment);
        return result;
    }

84:
yml

server:
  port: 84

spring:
  application:
    name: nacos-order-consumer
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    sentinel:
      transport:
        #配置Sentinel dashboard地址
        dashboard: localhost:8080
        # 默认8719端口,假如被占用了会自动从8719端口+1进行扫描,直到找到未被占用的 端口
        port: 8719

#消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者)
service-url:
  nacos-user-service: http://nacos-payment-provider

controller

@RequestMapping("/consumer/fallback/{id}")
//    @SentinelResource(value = "fallback",fallback = "handlerFallback")
//    @SentinelResource(value = "fallback",blockHandler = "blockHandler")
    @SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler")
    public CommonResult<Payment> fallback(@PathVariable Long id ){
        CommonResult<Payment> result=restTemplate.getForObject(serverURL+"/paymentSQL/"+id,CommonResult.class,id);
        if(id == 4){
            throw new IllegalArgumentException("IllegalArgumentException ,非法参数异常");
        }else if(result.getData() == null){
            throw new NullPointerException("NullPointerException ,没有该条记录,空指针了");
        }
        return result;

    }


    public  CommonResult handlerFallback(@PathVariable Long id,Throwable e){
        Payment payment = new Payment(id,null);
        return new CommonResult<>(444,"兜底的handlerFallback 触发"+e.getMessage(),payment);
    }

    public  CommonResult blockHandler(@PathVariable Long id, BlockException e){
        Payment payment = new Payment(id,null);
        return new CommonResult<>(444,"blockHandler -sentinel 限流 触发"+e.getMessage(),payment);
    }

主启动记得加@EnableDiscoveryClient

fallback 管运行异常
blockHandler管配置异常

目前配置
在这里插入图片描述

效果:
在这里插入图片描述

Sentinel服务熔断fallback和blockHandler配置

依次打开fallback 方法上面的注解并测试会发现
fallback 处理运行异常
blockHandler处理限流异常
如果同时触发 限流在前 异常在后

Sentinel服务熔断exceptionsToIgnore

添加的异常不进行fallback处理
在这里插入图片描述

Sentinel服务熔断OpenFeign

pom 中添加

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

yml

#激活sentinel对feign的支持
feign:
  sentinel:
    enabled: true

service

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

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

}

PaymentFallbackService就不写了实现PaymentService 接口并重写方法
controller中添加

 @Resource
    private PaymentService paymentService;
    
@GetMapping(value = "/consumer/openfeign/paymentSQL/{id}")
    public CommonResult<Payment> paymentSQL(@PathVariable Long id){
        return paymentService.paymentSQL(id);
    }

启动类加@EnableFeignClients
就好了

坑:
启动报错:
在这里插入图片描述
问题:版本问题:
在这里插入图片描述
解决方案:
具体代码和理由和github说明:https://blog.csdn.net/pointer_v/article/details/104989935
在这里插入图片描述

Sentinel持久化规则

sentinel配置没有做持久化之前的配置会在重启后消失
pom

        <!-- SpringCloud ailibaba sentinel-datasource-nacos 持久化需要用到-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>

yml

datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            dataId: cloudalibaba-sentinel-service
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow

在这里插入图片描述

nacos
在这里插入图片描述

[
    {
        "resource": "/byResource",
        "limitApp": "default",
        "grade": 1,
        "count": 1,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    },
    {
        "resource": "/testMyhandler",
        "limitApp": "default",
        "grade": 1,
        "count": 1,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    }
]

SpringCloud-整体学习(十二) Seata(分布式事务)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值