【Spring Cloud Alibaba】【Hoxton】Sentinel 热点规则-@SentinelResource-熔断-持久化(二)

news/2024/7/5 18:01:37

1 Nacos 入门-配置中心-集群
2 Sentinel 入门-限流-降级(一)
3 Sentinel 热点规则-@SentinelResource-熔断-持久化(二)
4 Seata从入门到实战

1 热点参数限流

何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如:

  • 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制
  • 用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制
    热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。
    在这里插入图片描述

1.1 新建Controller

@RestController
public class HotkeyController {
    /**
     * SentinelResource: sentinel相关配置,value唯一,blockHandler回调方法
     */
    @GetMapping("/hotkey")
    @SentinelResource(value = "hotkey",blockHandler = "dealHotkey")
    public String hotkey(@RequestParam(value = "key",required = false) String key){
        return "hello hotkey,  O(∩_∩)O";
    }
    public String dealHotkey(String key, BlockException e){
        return "调用失败,   o(╥﹏╥)o";
    }
}

1.2 新建热点规则

解释:资源名为@SentinelResource的value值,阈值是qp的值,统计时长是发生后1秒内降级。
在这里插入图片描述

1.3 测试

随便调用:http://localhost:9004/hotkey
在这里插入图片描述
调用http://localhost:9004/hotkey?key=sentinel频繁时:
在这里插入图片描述

1.4 参数例外项

期望当key为phone时qps为100,剩下的为1
在这里插入图片描述

狂点后仍然返回正确的行为:
在这里插入图片描述

2 @SentinelResource

2.1 按资源名称添加流控规则

(1) 创建Controller

@RestController
public class SentinelResourceController {
    @GetMapping("/resource")
    @SentinelResource(value = "resource",blockHandler = "handleException")
    public String resource(){
        return "SentinelResourceController invoke resource success";
    }
    public String handleException(BlockException e){
        return "SentinelResourceController invoke handleException";
    }
}

(2) 新建流控规则
在这里插入图片描述
(3) 刷新频繁会出现
在这里插入图片描述

2.2 自定义异常返回类

(1) 自定义handler

public class ZrsBlockHandler {
    public static String handler1Exception(BlockException exception){
        return  "ZrsBlockHandler invoke handler【1】Exception";
    }
    public static String handler2Exception(BlockException exception){
        return  "ZrsBlockHandler invoke handler【2】Exception";
    }
}

(2) 修改SentinelResourceController


@RestController
public class SentinelResourceController {
    @GetMapping("/resource")
    @SentinelResource(value = "resource",blockHandler = "handleException")
    public String resource(){
        return "SentinelResourceController invoke resource success";
    }
    public String handleException(BlockException e){
        return "SentinelResourceController invoke handleException";
    }
    @GetMapping("/handler1")
    @SentinelResource(value = "handler1Exception",blockHandlerClass = ZrsBlockHandler.class,
    blockHandler = "handler1Exception")
    public String handler1(){
        return "SentinelResourceController invoke resource success";
    }

    @GetMapping("/handler2")
    @SentinelResource(value = "handler2Exception",blockHandlerClass = ZrsBlockHandler.class,
            blockHandler = "handler2Exception")
    public String handler2(){
        return "SentinelResourceController invoke resource success";
    }
}

(3) 启动服务

http://localhost:9004/handler1
http://localhost:9004/handler2

(4) 添加流控规则
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
(5) 频繁访问
在这里插入图片描述

在这里插入图片描述

3 熔断

3.1 环境准备

(1) 初始化环境

#代码为【Spring Cloud Alibaba】【Hoxton】Nacos 入门-配置中心-集群。文章中的代码,或者直接访问该文章底部的github
#文章机票为https://blog.csdn.net/qq_34125999/article/details/104934796
provider,服务名provider,注册到nacos
provider-slave,服务名provider,注册到nacos
customer,服务名customer去nacos消费服务

在这里插入图片描述
(2)启动环境
在这里插入图片描述
(3) 测试
在这里插入图片描述

在这里插入图片描述

3.2 修改customer程序

(1) 修改pom


<dependencies>
    <!--sentinel nacos-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>sentinel-datasource-nacos</artifactId>
    </dependency>
    <!--sentinel-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    <!--spring cloud alibaba-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</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-starter-test</artifactId>
    </dependency>
    <!--devtools热部署-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
        <scope>true</scope>
    </dependency>
</dependencies>

(2) 修改application.yml

server:
  port: 9002
spring:
  application:
    name: customer
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.0.39:8848
    sentinel:
      transport:
        #配置sentinel地址,端口
        dashboard: 192.168.0.39:8080
        port: 8719
        #客户端IP
        client-ip: 192.168.0.100

(3) 修改CustomerController

@RestController
@RequestMapping("/customer")
public class CustomerController {
    @Autowired
    private RestTemplate restTemplate;

    private final String SERVER_URL="http://provider"

    @GetMapping(value = "/hello")
    @SentinelResource(value = "hello")
    public String hello(){
        return restTemplate.getForObject(SERVER_URL+"/provider/hello", String.class);
    }
}

(4) 启动主程序后访问

http://localhost:9002/customer/hello

(5) 查看sentinel页面
在这里插入图片描述

3.3 fallback

(1) 修改CustomerController

@RestController
@RequestMapping("/customer")
public class CustomerController {
    @Autowired
    private RestTemplate restTemplate;

    private final String SERVER_URL="http://provider";

    @GetMapping(value = "/hello/{id}")
    @SentinelResource(value = "hello",fallback = "fallbackHandler")
    public String hello(@PathVariable("id") String id){
        if (id.equals("1")){
            throw new RuntimeException("id不能为1");
        }
        return restTemplate.getForObject(SERVER_URL+"/provider/hello", String.class);
    }

    public String fallbackHandler(@PathVariable("id") String id ,Throwable e){
        return "CustomerController invoke fallbackHandler";
    }
}

(2) 测试
在这里插入图片描述

在这里插入图片描述

3.4 blockHandler

(1) 修改CustomerController,仅配置blockHandler

@RestController
@RequestMapping("/customer")
public class CustomerController {

    @Autowired
    private RestTemplate restTemplate;

    private final String SERVER_URL="http://provider";

    /**
     *  blockHandler:仅负责sentinel违规
     */
    @GetMapping(value = "/hello/{id}")
    @SentinelResource(value = "hello",blockHandler = "helloBlockHandler")
    public String hello(@PathVariable("id") String id){
        if (id.equals("1")){
            throw new RuntimeException("id不能为1");
        }
        return restTemplate.getForObject(SERVER_URL+"/provider/hello", String.class);
    }
    public String fallbackHandler(@PathVariable("id") String id ,Throwable e){
        return "CustomerController invoke fallbackHandler";
    }
    public String helloBlockHandler(String id,BlockException e){
        return "CustomerController invoke blockHandler";
    }
}

(2) sentinel配置
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
(3) 测试

#访问1时直接报错,java没有对应fallback处理
http://localhost:9002/customer/hello/1
#当频繁访问,出现限流响应
http://localhost:9002/customer/hello/2

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

3.5 fallback、blockHandler同时配置

(1) 修改CustomerController

@RestController
@RequestMapping("/customer")
public class CustomerController {

    @Autowired
    private RestTemplate restTemplate;

    private final String SERVER_URL="http://provider";

    /**
     *  blockHandler:仅负责sentinel违规
     */
    @GetMapping(value = "/hello/{id}")
    @SentinelResource(value = "hello",blockHandler = "helloBlockHandler",fallback = "fallbackHandler")
    public String hello(@PathVariable("id") String id){
        System.out.println(id);
        if (id.equals("1")){
            throw new RuntimeException("id不能为1");
        }
        return restTemplate.getForObject(SERVER_URL+"/provider/hello", String.class);
    }


    public String fallbackHandler(@PathVariable("id") String id ,Throwable e){
        return "CustomerController invoke fallbackHandler";
    }


    public String helloBlockHandler(String id,BlockException e){
        return "CustomerController invoke blockHandler";
    }


}

(2) 测试

#java异常fallback->fallbackHandler
http://localhost:9002/customer/hello/1
#限流控制->helloBlockHandler
http://localhost:9002/customer/hello/2

在这里插入图片描述

在这里插入图片描述

3.6 OpenFegin

(1) 创建工程
在这里插入图片描述

(2) pom

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <!--sentinel nacos-->
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-datasource-nacos</artifactId>
    </dependency>
    <!--sentinel-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    <!--spring cloud alibaba-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</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-starter-test</artifactId>
    </dependency>
    <!--devtools热部署-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
        <scope>true</scope>
    </dependency>
</dependencies>

(3) application.yml

server:
  port: 9005
spring:
  application:
    name: customer-fegin
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.0.39:8848
    sentinel:
      transport:
        #配置sentinel地址,端口
        dashboard: 192.168.0.39:8080
        port: 8719
        #客户端IP
        client-ip: 192.168.0.100
#开启sentinel 对fegin的支持
feign:
  sentinel:
    enabled: true

(4) 主启动类

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

(5) 降级类

@Service
public class ProviderServiceFallback implements ProviderService {
    @Override
    public String hello() {
        return "ProviderServiceFallback invoke hello";
    }
}

(6) Fegin服务类


@FeignClient(value = "provider",path = "/provider",fallback = ProviderServiceFallback.class)
@Service
public interface ProviderService {
    @GetMapping("/hello")
    String hello();
}

(7) Controller

@RestController
@RequestMapping("/fegin")
public class FeginController {

    @Autowired
    private ProviderService providerService;

    @GetMapping("/hello")
    @SentinelResource(value = "hello")
    public String hello(){
        return providerService.hello();
    }
}

(8) 启动主程序

#报错
com.alibaba.cloud.sentinel.feign.SentinelContractHolder.parseAndValidateMetadata(Ljava/lang/Class;)
#解决办法,修改父pomspringcloud版本为Hoxton.SR1。- -,BUG。期待后续解决 - -!!!,修改后重启解决
<spring-cloud.version>Hoxton.SR1</spring-cloud.version>

在这里插入图片描述
在这里插入图片描述
(9) 测试
在这里插入图片描述

在这里插入图片描述

4 持久化配置

当关闭FeginApplication时,打开sentinel页面
在这里插入图片描述

4.1 修改customer-fegin的application.yml

server:
  port: 9005
spring:
  application:
    name: customer-fegin
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.0.39:8848
    sentinel:
      transport:
        dashboard: 192.168.0.39:8080
        port: 8719
        client-ip: 192.168.0.100
      datasource:
        na:
          nacos:
            server-addr: 192.168.0.39:8848
            groupId: DEFAULT_GROUP
            dataId: customer-fegin
            rule-type: flow
#开启sentinel 对fegin的支持
feign:
  sentinel:
    enabled: true

4.2 nacos添加配置

(1) 新建配置
在这里插入图片描述
(2) json串

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

(3) 参数解析

resource:资源名称;
IimitApp:来源应用;
grade:國值类型,0表示线程数,1表示QPS;
count:单机阈值
strategy:流控模式,0表示直接,1表示关联,2表示链路
controlbehavior:流控效果,0表示快速失败,1表示 Warm Up,2表示排队等待;
cluster Mode:是否集群。

(4) 查看列表
在这里插入图片描述

4.3 修改Controller

@RestController
@RequestMapping("/fegin")
public class FeginController {
    @Autowired
    private ProviderService providerService;

    @GetMapping("/hello")
    @SentinelResource(value = "hello",blockHandler = "helloBlockHandler")
    public String hello(){
        return  providerService.hello();
    }

    public String helloBlockHandler(BlockException e){
        return "CustomerController invoke blockHandler";
    }
}

4.3 启动主程序

#访问后,查看sentinelhttp://localhost:9005/fegin/hello

在这里插入图片描述

频繁访问后:
在这里插入图片描述

LAST GITHUB

#分支Sentinel-release-v1.0
https://github.com/zhurongsheng666/spring-cloud-alibaba

http://www.niftyadmin.cn/n/4556782.html

相关文章

3投资乘数k为多少 2均衡的储蓄量s为多少 已知消费函数为c=100+0.6y i=60试求1均衡国民收入y是多少

如果充业的Yf&#xff1d;1000 为使该经济达到充分就业的均衡状态 那么 so I300 so Y400(2)均衡的储蓄量S 即Y1000.6Y60 则投资量应满足YfCI1000.6YfI&#xff1d;1000 &#xff1a;(1)均衡的国民收入Y (3)如果充分就业的国民收入水平为Yf1000 当市均时SI60 根据产品市场均衡条…

【信源编码技术】实验2-Huffman编码

实验来源 《数据压缩导论&#xff08;第4版&#xff09;》&#xff08;Khalid Sayood著&#xff09;第三章 霍夫曼编码 项目与习题 实验内容 一、利用程序huff_enc和huff_dec进行以下操作&#xff08;在每种情况下&#xff0c;利用由被压缩图像生成的码本&#xff09;。 &a…

用XPath精确定位节点元素selenium使用Xpath定位之完整篇

在利用XSL进行转换的过程中&#xff0c;匹配的概念非常重要。在模板声明语句 xsl:template match ""和模板应用语句xsl:apply-templates select "" 中&#xff0c;用引号括起来的部分必须能够精确地定位节点。具体的定位方法则在XPath中给出。 之所以要在…

【Spring Cloud Alibaba】【Hoxton】Seata从入门到实战

1 Nacos 入门-配置中心-集群 2 Sentinel 入门-限流-降级&#xff08;一&#xff09; 3 Sentinel 热点规则-SentinelResource-熔断-持久化&#xff08;二&#xff09; 4 Seata从入门到实战 1 简介 官网地址&#xff1a;https://seata.io/zh-cn/1.1 Seata Seata 是一款开源的分…

【信源编码技术】实验3-均匀/矢量量化

实验准备 被压缩图像 按光栅扫描顺序存储的256*256像素8位灰度图sena.img sena.img程序 均匀量化编码器uqimg_enc 使用方法&#xff1a;uqimg_enc [ -i infile ][ -o outfile ][ -l numlev ][ -b numbits ][ -m max_value ][ -t min_value ][ -x row_size ][ -y col_size ]…

NullPointException

NullPointException 空指针&#xff0c;能看不能用转载于:https://www.cnblogs.com/yangzihong/p/9990217.html

c语言里 有什么分别

但第一个输出的第一个数应该是9 答案补充 嗯 下次打印的结果都是自加(自减)后的结果 答案补充 肯定不会一样的 答案补充 我运行过 a--是先打印再自减;而且 a是先自加再打印 --a是先自减再打印 只是a是先打印再自加 A--都是会执行的语句.不管在哪里出现它都会自加(自减) 然后a的…

day 4

shu ru fa huai le - - 转载于:https://www.cnblogs.com/L20160909/p/9991584.html