SpringCloud Aliba-Sentinel【下篇】-从入门到学废【6】

🤩java小课堂🤩

🌭🌭🌭== 和 equals 的区别是什么?🥹🥹🥹

  • 对于基本类型,== 比较的是值;
  • 对于引用类型,==比较的是地址;
  • equals不能用于基本类型的比较;
  • 如果没有重写equals, equals就相当于 ==;
  • 如果重写了 equals方法,equals比较的是对象的内容;

目录

🍿1.@SentinelResource

🧂[2. Ribbon系列](#2. Ribbon系列)

🧈3.Fegin系列

🥓4.规则持久化


1.@SentinelResource

1.1按资源名称限流

在对sentinel进行流控设置时,资源名称应与@SentinelResource的value值保持一致,设置blockHander返回兜底方法,否则返回sentinel默认的

java 复制代码
    @GetMapping("/byResource")
    @SentinelResource(value = "byResource",blockHandler = "defaultException")
    public CommonResult byResource(){
        return new CommonResult(200,"按资源名称限流",new Payment(2023,"serial001"));
    }

    public CommonResult defaultException(BlockException exception){
        return new CommonResult(404, exception.getClass().getCanonicalName()+"服务不可用");
    }

1.2按url地址限流

只设置@SentinelRsource的value值,使用url地址进行限流,返回sentinel默认的

java 复制代码
    @GetMapping("/byUrl")
    @SentinelResource(value = "byUrl")
    public CommonResult byUrl(){
        return new CommonResult(200,"按url限流",new Payment(2023,"serial001"));
    }

1.3自定义限流类

使用@SentinelResource的blockHandlerClass属性,定义兜底类,在使用blockHandler定义兜底的方法

java 复制代码
   @GetMapping("/payment/customerBlockHandler")
    @SentinelResource(value = "customerBlockHandler",blockHandlerClass = CustomerBlockHandler.class,blockHandler = "handlerException2")
    public CommonResult customerBlockHandler(){
        return new CommonResult(200,"按自定义限流",new Payment(2023,"serial003"));
    }

2. Ribbon系列

准备:服务提供者9003,9004;服务消费者84

2.1服务提供者

1.建工程

1.再父工程下分别创建9003,9004服务提供者

2.注意jdk和maven版本

2.改pom

XML 复制代码
  <dependencies>
        <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>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--springCloud alibaba Naocs-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>

3.改yml

Groovy 复制代码
server:
  port: 9003

#服务名名称
spring:
  application:
    name: nacos-payment-provider
  cloud:
    nacos:
      discovery:
        #nacos地址
        server-addr: 192.168.20.50:1111


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

4.主启动

java 复制代码
@SpringBootApplication
@EnableDiscoveryClient
public class PaymentMain9004 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentMain9004.class);
    }
}

5.业务类

java 复制代码
@RestController
public class PaymentController {
    @Value("${server.port}")
    private String serverPort;

    public static HashMap<Long, Payment> hashMap = new HashMap<>();

    static {
        hashMap.put(1L, new Payment(111, "小张"));
        hashMap.put(2L, new Payment(222, "小六"));
        hashMap.put(3L, new Payment(333, "小李"));
    }

    @GetMapping("/payment/{id}")
    public CommonResult<Payment> getPayment(@PathVariable("id") Long id) {
        Payment payment = hashMap.get(id);
        CommonResult<Payment> result = new CommonResult(200, "服务器端口:" + serverPort, payment);
        return result;
    }
}

6.测试

2.2 服务消费者

1.建工程

1.在父工程下创建服务84

2.注意jdk和maven版本

2.改pom

XML 复制代码
<dependencies>
        <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>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--springCloud alibaba Naocs-->
        <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>
        <!--openFeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

3.改yml

Groovy 复制代码
server:
  port: 84

spring:
  application:
    name: nacos-order-consumer
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.20.50:1111
    sentinel:
      transport:
        dashboard: localhost:8080
        prot: 8719

4.主启动

Groovy 复制代码
@SpringBootApplication
@EnableDiscoveryClient
public class Order84 {
    public static void main(String[] args) {
        SpringApplication.run(Order84.class);
    }
}

5.RestTemplate配置类

java 复制代码
@Configuration
public class MyConfig {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

6.业务类

java 复制代码
@RestController
public class ConsumerController {

    private static final String SERVER_NAME="http://nacos-payment-provider";

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/consumer/fallback/{id}")
    @SentinelResource(value = "fallback")
    public CommonResult<Payment> fallback(@PathVariable("id")Long id){
        CommonResult result = restTemplate.getForObject(SERVER_NAME + "/payment/" + id, CommonResult.class, id);
        if (result.getData()==null){
            throw new NullPointerException("没有记录");
        }
        return  result;
    }
}

7.测试

2.3fallback属性

  • fallback只管业务异常
  • @SentinelResource的fallBack属性,当有异常时,返回兜底方法handlerFallBack
java 复制代码
   @GetMapping("/consumer/fallback/{id}")
    @SentinelResource(value = "fallback", fallback = "handlerFallBack")
    public CommonResult<Payment> fallback(@PathVariable("id") int id) {
        CommonResult result = restTemplate.getForObject(SERVER_NAME + "/payment/" + id, CommonResult.class, id);
        if (result.getData() == null) {
            throw new NullPointerException("没有记录");
        }
        return result;
    }

    public CommonResult handlerFallBack(@PathVariable("id") int id, Throwable e) {
        Payment payment=new Payment(id,"null");
        return new CommonResult(404, "兜底方法," + e.getMessage(),payment);
    }

2.4blockhandler属性

  • blockhandler只负责Sentinel控制台配置违规
java 复制代码
    @GetMapping("/consumer/fallback/{id}")
    @SentinelResource(value = "fallback", blockHandler = "blockHandler")
    public CommonResult<Payment> fallback(@PathVariable("id") int id) {
        CommonResult result = restTemplate.getForObject(SERVER_NAME + "/payment/" + id, CommonResult.class, id);
        if (result.getData() == null) {
            throw new NullPointerException("没有记录");
        }
        return result;
    }

    public CommonResult blockHandler(@PathVariable("id") int id, BlockException blockException) {
        Payment payment = new Payment(id, "null");
        return new CommonResult(404, "blockHandler:" + blockException.getMessage(),payment);
    }

2.5fallback和blockhandler同时配置

若blockHandler和fallback都配置了,则被限流降级而抛出BlockException时只会进入blodkHandler处理逻辑。

java 复制代码
    @GetMapping("/consumer/fallback/{id}")
    @SentinelResource(value = "fallback", blockHandler = "blockHandler", fallback = "handlerFallBack")
    public CommonResult<Payment> fallback(@PathVariable("id") int id) {
        CommonResult result = restTemplate.getForObject(SERVER_NAME + "/payment/" + id, CommonResult.class, id);
        if (result.getData() == null) {
            throw new NullPointerException("没有记录");
        }
        return result;
    }

    public CommonResult blockHandler(@PathVariable("id") int id, BlockException blockException) {
        Payment payment = new Payment(id, "null");
        return new CommonResult(404, "blockHandler:" + blockException.getMessage(), payment);
    }


    public CommonResult handlerFallBack(@PathVariable("id") int id, Throwable e) {
        Payment payment = new Payment(id, "null");
        return new CommonResult(404, "兜底方法," + e.getMessage(), payment);
    }

3.Fegin系列

1.改pom

添加依赖

XML 复制代码
        <!--openFeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

2.改yml

激活feign

Groovy 复制代码
#激活Sentinel对Feign的支持
feign:
  sentinel:
    enabled: true

3.加Feign接口

添加feign接口,与调用方法一致

java 复制代码
@FeignClient(value = "nacos-payment-provider",fallback = PaymentFallbackFeign.class)
public interface PaymentFeign {

    @GetMapping("/payment/{id}")
    public CommonResult<Payment> getPayment(@PathVariable("id") Long id);
}

兜底方法

java 复制代码
@Component
public class PaymentFallbackFeign implements PaymentFeign{
    @Override
    public CommonResult<Payment> getPayment(Long id) {
        return new CommonResult<>(404,"服务降级返回----PaymentFallbackFeign"); 
    }
}

4.主启动

添加@EnableFeignClients

java 复制代码
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class Order84 {
    public static void main(String[] args) {
        SpringApplication.run(Order84.class);
    }
}

5.业务类

java 复制代码
  @Autowired
    private PaymentFeign paymentFeign;

    @GetMapping("/consumer/payment/{id}")
    public CommonResult<Payment> getPayment(@PathVariable("id") Long id){
     return paymentFeign.getPayment(id);
    }

6.测试

关闭服务提供者9003,9004,消费者84不会被耗死

4.规则持久化

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

1.改pom

XML 复制代码
        <!--持久化-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>

2.改yml

Groovy 复制代码
server:
  port: 8401

spring:
  application:
    name: cloudalibaba-sentinel-service

  cloud:
    nacos:
      discovery:
        #nacos服务注册中心
        server-addr: 192.168.20.50:1111
    sentinel:
      transport:
        #sentinel dashboard地址
        dashboard: localhost:8080
        #默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口
        port: 8719
        #将Sentinel流控规则持久化到nacos
      datasource:
        ds1:
          nacos:
            server-addr: 192.168.20.50:1111
            dataId: ${spring.application.name}
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow

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

3.添加nacos配置

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

4.测试

启动8401后,流控规则生效

相关推荐
代码小鑫几秒前
A031-基于SpringBoot的健身房管理系统设计与实现
java·开发语言·数据库·spring boot·后端
Json____6 分钟前
学法减分交管12123模拟练习小程序源码前端和后端和搭建教程
前端·后端·学习·小程序·uni-app·学法减分·驾考题库
monkey_meng26 分钟前
【Rust类型驱动开发 Type Driven Development】
开发语言·后端·rust
落落落sss34 分钟前
MQ集群
java·服务器·开发语言·后端·elasticsearch·adb·ruby
我救我自己34 分钟前
UE5运行时创建slate窗口
java·服务器·ue5
2401_853275731 小时前
ArrayList 源码分析
java·开发语言
爪哇学长1 小时前
SQL 注入详解:原理、危害与防范措施
xml·java·数据库·sql·oracle
大鲤余1 小时前
Rust,删除cargo安装的可执行文件
开发语言·后端·rust
她说彩礼65万1 小时前
Asp.NET Core Mvc中一个视图怎么设置多个强数据类型
后端·asp.net·mvc
MoFe11 小时前
【.net core】【sqlsugar】字符串拼接+内容去重
java·开发语言·.netcore