Sentinel熔断与限流


Sentinel

主要特征

安装

firewall-cmd --zone=public --permanent --add-port=8080/tcp
firewall-cmd --zone=public --permanent --add-port=8719/tcp
firewall-cmd --zone=public --permanent --add-port=8720/tcp
firewall-cmd --reload
firewall-cmd --list-all

java -jar sentinel-dashboard-1.8.1.jar
# 后台启动
nohup java -jar sentinel-dashboard-1.8.1.jar
# 官网说可以用

-Dserver.port=8480 # 指定控制台的端口为8480
 
-Dcsp.sentinel.dashboard.server=localhost:8480 # 指定要被哪个控制台监控(这里指定的是自己监控自己)
 
-Dproject.name=sentinel-dashboard # 指定实例名称(名称会在控制台左侧以菜单显示)
 
-Dsentinel.dashboard.auth.username=sentinel # 设置登录的帐号为:sentinel
 
-Dsentinel.dashboard.auth.password=123456 # 设置登录的密码为:123456

我这个sentinel是部署在服务器端的

sentinel部署到本地会好一点,端口可以直接访问,部署到服务器端,Sentinel访问本地找不到,我这里做了内网穿透;可以用,好使

映射地图

本地端口 服务器映射端口
127.0.0.1:8401 101.200.40.242:18401
127.0.0.1:8719 101.200.40.242:18719

使用

规则简介

image-20230803110228279

application.yml

server:
  port: 8401
spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: 101.200.40.242:18848
    sentinel:
      transport:
        dashboard: 101.200.40.242:8080
        port: 8719
        clientIp: 101.200.40.242:18719
      datasource:
        ds1:
          nacos:
            server-addr: 101.200.40.242:18848
            dataId: cloudalibaba-sentinel-service
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow
management:
  endpoints:
    web:
      exposure:
        include: '*'

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

SentinelMain8401.java

@SpringBootApplication
@EnableDiscoveryClient
public class SentinelMain8401 {
    public static void main(String[] args) {
        SpringApplication.run(SentinelMain8401.class,args);
    }
}

FlowLimitController.java

@RestController
@Slf4j
public class FlowLimitController {

    @GetMapping("/testA")
    public String testA(){
        return "-------------testA";
    }

    @GetMapping("/testB")
    public String testB(){
        log.info(Thread.currentThread().getName()+"\t"+".....testB");
        return "-----------testB";
    }

}

配置规则

QPS限流

image-20230803105759196

正常 限流
image-20230803105627020 image-20230803105611151

线程限流

image-20230803110557535

关联限流

image-20230803110502971

通过postman 设置20个线程每0.3秒访问一下testB;然后testA就会被限流

设置postman

image-20230803112905941

访问testA

image-20230803112608987

流控 预热

image-20230803113039606

排队等待

image-20230803113333716

Sentinel降级

RT

image-20230803113943236

-Dcsp.sentinel.statistic.max.rt=XXX

jmeter设置

image-20230803120212494 image-20230803120244455

控制台输出

image-20230803120040219

浏览器输出

关闭jemter10个线程之后,可以正常访问

image-20230803120349613

异常比例

更改controller中的方法

@GetMapping("/testD")
public String testD(){
    try{
        TimeUnit.SECONDS.sleep(1);
    }catch (InterruptedException e){
        e.printStackTrace();
    }
    int age=10/0;
    log.info("testD异常比例");
    return "----------testD";
}

设置降级规则

image-20230803140344057

开启jmeter

访问浏览器

image-20230803140552408

异常比数

添加配置

image-20230803140724257

访问超过五次就会报错

image-20230803141055737

Sentinel 热点 key

@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 exception){
    return "----------------deal_testHotKey";//sentinel 系统默认的提示 Blocked by Sentinel (flow limiting)
}

添加配置

image-20230803141900860

image-20230803142032614 image-20230803142015199

当参数为5的时候,限流阈值为200

image-20230803142449431

当参数不为5时,多次点击 参数时5时,多次点击
image-20230803142557877 image-20230803142631042

注意:

​ @SentinelResource

​ 处理的是sentinel控制台配置的违规情况,有回调方法配置的兜底处理

运行时异常 @SentinelResource是不管

Sentinel 系统规则

image-20230803143139227

Sentinel Resource 配置

按资源名称限流+后续处理

创建新的controller

@RestController
@Slf4j
public class RateLimitController {
    @GetMapping("/byResource")
    @SentinelResource(value = "byResource",blockHandler = "handleException")
    public CommonResult byResource(){
        return new CommonResult(200,"按资源名称限流测试OK",new Payment(2023L,"serial001"));
    }
    public CommonResult handleException(BlockException e){
        return new CommonResult(444,e.getClass().getCanonicalName()+"\t 服务不可用");
    }
}

访问/byResource

image-20230803143942794

配置流控规则

image-20230803144206876

限流

image-20230803144253860

按url地址限流+后续处理

@GetMapping("/rateLimit/byUrl")
@SentinelResource(value = "byUrl")
public CommonResult byUrl(){
    return new CommonResult(200,"按URL地址限流测试OK",new Payment(2023L,"serial002"));
}

访问/rateLimit/byUrl

image-20230803144638423

添加配置

image-20230803144809705

再次访问,并多次刷新;能访问到和不能访问

image-20230803144856348

自定义限流处理逻辑

创建CustomerBlockHandler类用于自定义限流处理逻辑

public class CustomerBlockHandler {
    public static CommonResult handlerEXception(BlockException e){
        return new CommonResult(444,"自定义限流处理信息1   -----1");
    }
    public static CommonResult handlerEXception2(BlockException e){
        return new CommonResult(444,"自定义限流处理信息2   ------2");
    }
}
@GetMapping("rateLimit/customerBlockHandler")
@SentinelResource(value ="customerBlockHandler",
                  blockHandlerClass = CustomerBlockHandler.class,//指定处理方法类型
                  blockHandler = "handlerEXception"//指定处理方法函数
                 )
public CommonResult customerBlockHandler(){
    return new CommonResult(200,"客户自定义限流处理逻辑",new Payment(2023L,"serial003"));
}

访问/rateLimit/customerBlockHandler

添加配置

image-20230803150017356

image-20230803145925760 image-20230803145941074


文章作者: 毛豆不逗比
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 毛豆不逗比 !
  目录
{% include '_third-party/exturl.swig' %} {% include '_third-party/bookmark.swig' %} {% include '_third-party/copy-code.swig' %} + {% include '_custom/custom.swig' %}