IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 【Java】SpringCloud:Eureka、Ribbon、OpenFeign、Hystrix -> 正文阅读

[Java知识库]【Java】SpringCloud:Eureka、Ribbon、OpenFeign、Hystrix

SpringCloud

概述

  1. Spring Cloud是一系列框架的有序集合。
  2. Spring Cloud的本质是在 Spring Boot 的基础上,增加了一堆微服务相关的规范,并对应用上下文 (Application Context )进行了功能增强。
  3. 它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。
优点缺点
通过服务的原子化拆分,以及微服务的独立打包、部署和升级,小团队的交付周期将缩短,运维成本也将大幅度下降微服务过多,服务治理成本高,不利于系统维护。
微服务遵循单一原则。微服务之间采用Restful等轻量协议传输。分布式系统开发的技术成本高(容错、分布式事务等)。

注意

微服务之间传递参数时 @RequestBody @PathVariable 不能省略!

spring:
  application:
    name: eureka  #微服务项目的名字,会在注册中心中出现

RestTempalte

代码:

消费者代码:

package com.sms.controller;

import com.sms.entity.RespEntity;
import com.sms.entity.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * @Author songmingsong
 * @Version V1.0.0
 * @Date 2022-09-23 17:44
 */
@RestController
@RequestMapping("/conStudent")
public class StudentController {
    @Autowired
    RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;


    /**
     * eureka 获取实例地址方法
     * 
     * @return
     */
    public String serviceUri() {
        // provider-student 服务提供者
        List<ServiceInstance> serviceInstances = discoveryClient.getInstances("provider-student");
        if (serviceInstances != null && serviceInstances.size() > 0) {
            return serviceInstances.get(0).getUri() + "/student/";
        }
        return null;
    }


    @GetMapping("/{id}")
    public RespEntity getStuInfo(@PathVariable("id") Integer id) {
        System.out.println("获取一个学生信息");
        //远程调用
        return restTemplate.getForObject(serviceUri() + id,
                RespEntity.class);
    }

    @GetMapping("/")
    public RespEntity getAllStudent() {
        System.out.println("获取所有学生信息");
        //远程调用
        return restTemplate.getForObject(serviceUri(),
                RespEntity.class);
    }

    @PostMapping("/")
    public RespEntity addStudent(@RequestBody Student student) {
        System.out.println("添加学生");
        System.out.println(student);
        return restTemplate.postForObject(serviceUri(), student, RespEntity.class);
    }
}

提供者代码:

package com.sms.controller;

import com.sms.entity.RespEntity;
import com.sms.entity.Student;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;

/**
 * @Author songmingsong
 * @Version V1.0.0
 * @Date 2022-09-23 17:31
 */
@RestController
@RequestMapping("/student")
public class StudentController {
    @Value("${server.port}")
    private Integer port;

    @GetMapping("/{id}")
    public RespEntity getStudent(@PathVariable("id") Integer id) {
        if (id == 1) {
            return new RespEntity(1, "ok"+port, new Student(1, "test1", 12));
        }
        return new RespEntity(2, "ok"+port, new Student(2, "test2", 11));
    }

    @GetMapping("/")
    public RespEntity getAllStudent() {
        return new RespEntity(2, "ok"+port, Arrays.asList(
                new Student(1, "test1", 12),
                new Student(2, "test2", 11),
                new Student(3, "test3", 13)
        ));
    }

    @PostMapping("/")
    public RespEntity addStudent(@RequestBody Student student) {
        System.out.println(student);
        return new RespEntity(200, "ok"+port, null);
    }
}

Eureka

概述:

Eureka是Net?ix开发的服务发现框架,SpringCloud将它集成在自己的子项目spring-cloud-net?ix中, 实现SpringCloud的服务发现功能。

微服务注册中心

原理:注册中心可以说是微服务架构中的通讯录,它记录了服务和服务地址的映射关系。在分布式架构中,服务会注册到注册中心,当服务需要调用其它服务时,就到注册中心找到服务的地址,进行调用。

常见的注册中心:

组件名语言CAP一致性算法对外暴露接口
EurekaJavaAPHTTP
ConsulGoCPRaftHTTP/DNS
ZookeeperJavaCPPaxos客户端
NacosJavaAPRaftHTTP

CAP:三进二

C:一致性;

A:可用性;

P:分区容错性

在微服务下,分区容错性是必须实现,其一致性和可用性二选一,为了优化用户体验,一般会优先实现可用性,保证服务是可用状态。

基本架构:

Eureka Server :提供服务注册和发现 ;

Eureka Client

? Service Provider :服务提供方(将自身服务注册到Eureka ,从而使服务消费方能够找到 )

? Service Consumer : 服务消费方 (从Eureka获取注册服务列表,从而能够消费服务)

  1. Eureka Server提供服务发现的能力,各个微服务启动时,会通过Eureka Client向Eureka Server 进行注册自己的信息(例如网络信息),Eureka Server会存储该服务的信息;
  2. 微服务启动后,会周期性地向Eureka Server发送心跳(默认周期为30秒)以续约自己的信息。如果Eureka Server在一定时间内没有接收到某个微服务节点的心跳,Eureka Server将会注销该微服 务节点(默认90秒);
  3. 每个Eureka Server同时也是Eureka Client ,多个Eureka Server之间通过复制的方式完成服务注册表的同步;
  4. Eureka Client会缓存Eureka Server中的信息。即使所有的Eureka Server节点都宕掉,服务消费者依然可以使用缓存中的信息找到服务提供者

自我保护:

  1. 微服务第一次注册成功之后,每30秒会发送一次心跳将服务的实例信息注册到注册中心。通知 Eureka Server该实例仍然存在。
  2. 如果超过90秒没有发送更新,则服务器将从注册信息中将此服务移除。
  3. Eureka Server在运行期间,会统计心跳失败的比例在15分钟之内是否低于85% ,如果出现低于的情况,Eureka Server会 将当前的实例注册信息保护起来,同时提示这个警告。
  4. 保护模式主要用于一组客户端和Eureka Server 之间存在网络分区场景下的保护。一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务

关闭自我保护功能: eureka.service.enableSelfPreservation=false

服务剔除:

lease-renewal-interval-in-seconds: 服务续约(renew)的间隔, 默认为30秒

lease-expiration-duration-in-seconds: 服务失效时间,默认值90秒

也就是说,默认情况下每隔30秒服务会向注册中心发送一次心跳, 证明自己还活着。如果超过90秒没有发送心跳,EurekaServer就会认为该服务宕机,会定时(eureka.server.eviction-interval-timer.in-ms设定的时间,默认60秒) 从服务列表中移除,这两个值在生产环境不要修改,默认即可。

服务续约:

在注册服务完成以后,服务提供者会维持一个心跳(定时向EurekaServer发起Rest请求) 。告诉EurekaServer: “我还活着"。称为服务的续约(renew) ;

服务失效:

lease-expiration-duration-in-seconds: 服务失效时间,默认值90秒

代码

pom:

<!--eureka 依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

yml:

服务端:

server:
  port: 6061
spring:
  application:
    name: eureka #微服务项目的名字,会在注册中心中出现
eureka:
  instance:
    hostname: localhost  #实例名
  client:
#    registerWithEureka: false # 是否将自己挂到注册中心上,单节点可以false,集群true
#    fetchRegistry: false # 是否要去注册获取服务列表
    registerWithEureka: true # 是否将自己挂到注册中心上,单节点可以false,集群true
    fetchRegistry: true # 是否要去注册获取服务列表
    serviceUrl:
      defaultZone: http://localhost:6061/eureka/ #Eureka服务地址
#      defaultZone: http://localhost:6061/eureka/,http://localhost:6062/eureka/ #Eureka服务地址
  server:
    enable-self-preservation: false #禁用自我保护
    #private long evictionIntervalTimerInMs = 60000L;
    #启用删除的默认时间:默认60s启动一次剔除服务,将无效的服务从服务列表删除
    eviction-interval-timer-in-ms: 2000

客户端:

server:
  # 端口
  port: 8081
spring:
  application:
    name: provider-student
eureka:
  client:
    registerWithEureka: true # 是否将自己挂到注册中心上,单节点可以false,集群true
    fetchRegistry: true # 是否要去注册获取服务列表
    serviceUrl:
#      defaultZone: http://localhost:6061/eureka/,http://localhost:6062/eureka/ #Eureka服务地址
      defaultZone: http://localhost:6061/eureka/ #Eureka服务地址
  instance:
    #服务续约时间:客户端每隔30秒发送一个心跳包
    lease-renewal-interval-in-seconds: 1
    #失效时间:  客户端超过90秒没有发送心跳包,服务器就可以认为当前服务下线
    lease-expiration-duration-in-seconds: 2

服务提供者:

package com.sms.controller;

import com.sms.entity.RespEntity;
import com.sms.entity.Student;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;

/**
 * @Author songmingsong
 * @Version V1.0.0
 * @Date 2022-09-23 17:31
 */
@RestController
@RequestMapping("/student")
public class StudentController {
    @Value("${server.port}")
    private Integer port;

    @GetMapping("/{id}")
    public RespEntity getStudent(@PathVariable("id") Integer id) {
        if (id == 1) {
            return new RespEntity(1, "ok"+port, new Student(1, "test1", 12));
        }
        return new RespEntity(2, "ok"+port, new Student(2, "test2", 11));
    }

    @GetMapping("/")
    public RespEntity getAllStudent() {
        return new RespEntity(2, "ok"+port, Arrays.asList(
                new Student(1, "test1", 12),
                new Student(2, "test2", 11),
                new Student(3, "test3", 13)
        ));
    }

    @PostMapping("/")
    public RespEntity addStudent(@RequestBody Student student) {
        System.out.println(student);
        return new RespEntity(200, "ok"+port, null);
    }
}

服务消费者:

package com.sms.controller;

import com.sms.entity.RespEntity;
import com.sms.entity.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * @Author songmingsong
 * @Version V1.0.0
 * @Date 2022-09-23 17:44
 */
@RestController
@RequestMapping("/conStudent")
public class StudentController {
    @Autowired
    RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;


    /**
     * eureka 获取实例地址方法
     *
     * @return
     */
    public String serviceUri() {
        List<ServiceInstance> serviceInstances = discoveryClient.getInstances("provider-student");
        if (serviceInstances != null && serviceInstances.size() > 0) {
            return serviceInstances.get(0).getUri() + "/student/";
        }
        return null;
    }


    @GetMapping("/{id}")
    public RespEntity getStuInfo(@PathVariable("id") Integer id) {
        System.out.println("获取一个学生信息");
        //远程调用
        return restTemplate.getForObject(serviceUri() + id,
                RespEntity.class);
    }

    @GetMapping("/")
    public RespEntity getAllStudent() {
        System.out.println("获取所有学生信息");
        //远程调用
        return restTemplate.getForObject(serviceUri(),
                RespEntity.class);
    }

    @PostMapping("/")
    public RespEntity addStudent(@RequestBody Student student) {
        System.out.println("添加学生");
        System.out.println(student);
        return restTemplate.postForObject(serviceUri(), student, RespEntity.class);
    }
}

Ribbon

概述:

Ribbon是 Net?ix发布的一个负载均衡器,有助于控制 HTTP 和 TCP客户端行为。

在 SpringCloud 中,Eureka一般配合Ribbon进行使用,Ribbon提供了客户端负载均衡的功能,Ribbon利用从Eureka中读取到的服务信息,在调用服务节点提供的服务时,会合理的进行负载。

在SpringCloud中可以将注册中心和Ribbon配合使用,Ribbon自动的从注册中心中获取服务提供者的 列表信息,并基于内置的负载均衡算法,请求服务

主要作用:

服务调用负载均衡
基于Ribbon实现服务调用, 是通过拉取到的所有服务列表组成(服务名-请求路径的)映射关系。借助 RestTemplate 最终进行调用当有多个服务提供者时,Ribbon可以根据负载均衡的算法自动的选择需要调用的服务地址

负载均衡:

两种方式:

服务端客户端
先发送请求到负载均衡服务器或者软件,然后通过负载均衡算法,在多个服务器之间选择一个进行访问;即在服务器端再进行负载均衡算法分配客户端会有一个服务器地址列表,在发送请求前通过负载均衡算法选择一个服务器,然后进行访问,这是客户端负载均衡;即在客户端就进行负载均衡算法分配

负载均衡策略:

com.netflix.loadbalancer.IRule顶级接口
com.netflix.loadbalancer.RoundRobinRule以轮询的方式进行负载均衡。
com.netflix.loadbalancer.RandomRule随机策略
com.netflix.loadbalancer.RetryRule重试策略。
com.netflix.loadbalancer.WeightedResponseTimeRule权重策略。会计算每个服务的权 重,越高的被调用的可能性越大。
com.netflix.loadbalancer.BestAvailableRule最佳策略。遍历所有的服务实例,过滤掉 故障实例,并返回请求数最小的实例返回。
com.netflix.loadbalancer.AvailabilityFilteringRule可用过滤策略。过滤掉故障和请 求

代码:

@Configuration
public class RestTemplateConfiguration {

    @LoadBalanced
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}
@RequestMapping("/consumerstudent")
public class ConsumerStudent {

    @Autowired
    RestTemplate restTemplate;
    
    // 直接使用服务名(provider-student)服务提供者
    public String serviceUrl() {
        return "http://provider-student/student/";
    }
    
    
    @GetMapping("/{id}")
    public RespEntity getStuInfo(@PathVariable("id") Integer id) {
        System.out.println("获取一个学生信息");
        //远程调用
        return restTemplate.getForObject(serviceUri() + id,
                RespEntity.class);
    }
}

OpenFeign

概述:

  1. Feign是Net?ix开发的声明式,模板化的HTTP客户端。
  2. Feign可帮助我们更加便捷,优雅的调用HTTP API。
  3. 在SpringCloud中,使用Feign非常简单——创建一个接口,并在接口上添加一些注解,代码就完成了。
  4. SpringCloud对Feign进行了增强,使Feign支持了SpringMVC注解,并整合了Ribbon和Eureka ,从而让Feign的使用更加方便。

负载均衡:

Feign中本身已经集成了Ribbon依赖和自动配置,因此我们不需要额外引入依赖,也不需要再注册RestTemplate 对象

超时控制:

默认Feign客户端只等待1秒钟,但是服务端处理需要超过1秒钟,导致Feign客户端不想等待了 ,直接返回报错。

为了避免这样的情况,有时候我们需要设置Feign客户端的超时控制。

可以在ymI文件中开启配置

#微服务调用超时配置
feign:
  client:
    config:
      default:  #default指定对所有的微服务有效,可以指定具体的微服务名
        connectTimeout: 5000
        readTimeout: 5000

日志打印:

配置

#微服务调用超时配置
feign:
  client:
    config:
      default:  #default指定对所有的微服务有效,可以指定具体的微服务名
        connectTimeout: 5000
        readTimeout: 5000
        loggerLevel: full      #OpenFeign输出日志信息
#开启spring日志功能,级别:debug
logging:
  level:
    com.woniuxy.consumer.student.feignclient.StudentFeignClient: debug

代码:

客户端消费者:

pom

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

定义声明式接口:

package com.sms.FeignClient;

import com.sms.entity.RespEntity;
import com.sms.entity.Student;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

/**
 * @Author songmingsong
 * @Version V1.0.0
 * @Date 2022-09-27 11:53
 */
@FeignClient("provider-student")
public interface IStudentFeignClient {
    @GetMapping("/student/{id}")
    RespEntity getStudent(@PathVariable("id") Integer id);

    @GetMapping("/student/")
    RespEntity getAllStudent();

    @PostMapping("/student/")
    RespEntity addStudent(@RequestBody Student student);
}

调用接口

package com.sms.controller;

import com.sms.FeignClient.IStudentFeignClient;
import com.sms.entity.RespEntity;
import com.sms.entity.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * @Author songmingsong
 * @Version V1.0.0
 * @Date 2022-09-23 17:44
 */
@RestController
@RequestMapping("/feignstudent")
public class StudentFeignController {
    @Autowired
    IStudentFeignClient iStudentFeignClient;

    @GetMapping("/{id}")
    public RespEntity getStuInfo(@PathVariable("id") Integer id) {
        System.out.println("获取一个学生信息");
        return iStudentFeignClient.getStudent(id);
    }

    @GetMapping("/")
    public RespEntity getAllStudent() {
        System.out.println("获取所有学生信息");
        return iStudentFeignClient.getAllStudent();
    }

    @PostMapping("/")
    public RespEntity addStudent(@RequestBody Student student) {
        System.out.println("添加学生");
        System.out.println(student);
        return iStudentFeignClient.addStudent(student);
    }
}

客户端提供者:

package com.sms.controller;

import com.sms.entity.RespEntity;
import com.sms.entity.Student;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;

/**
 * @Author songmingsong
 * @Version V1.0.0
 * @Date 2022-09-23 17:31
 */
@RestController
@RequestMapping("/student")
public class StudentController {
    @Value("${server.port}")
    private Integer port;

    @GetMapping("/{id}")
    public RespEntity getStudent(@PathVariable("id") Integer id) {
        if (id == 1) {
            return new RespEntity(1, "ok"+port, new Student(1, "test1", 12));
        }
        return new RespEntity(2, "ok"+port, new Student(2, "test2", 11));
    }

    @GetMapping("/")
    public RespEntity getAllStudent() {
        return new RespEntity(2, "ok"+port, Arrays.asList(
                new Student(1, "test1", 12),
                new Student(2, "test2", 11),
                new Student(3, "test3", 13)
        ));
    }

    @PostMapping("/")
    public RespEntity addStudent(@RequestBody Student student) {
        System.out.println(student);
        return new RespEntity(200, "ok"+port, null);
    }
}

Hystrix

概述:

Hystrix是一个用于分布式系统的延迟和容错的开源库。

在分布式系统里,许多依赖不可避免的调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整个服务失败,避免级联故障,以提高分布式系统的弹性。

解决问题:服务雪崩

在微服务架构中通常会有多个服务层调用,基础服务的故障可能会导致级联故障,进而造成整个系统不可用的情况,这种现象被称为服务雪崩效应。服务雪崩效应是一种因“服务提供者"的不可用导致“服务消费者”的不可用,并将不可用逐渐放大的过程。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6sqwieGD-1664275921881)(C:\Users\29295\AppData\Roaming\Typora\typora-user-images\image-20220927182115524.png)]

服务正常时:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hsf6pvum-1664275921882)(C:\Users\29295\AppData\Roaming\Typora\typora-user-images\image-20220927182124170.png)]

其中一个系统出现问题时:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nyqaRm6Z-1664275921883)(C:\Users\29295\AppData\Roaming\Typora\typora-user-images\image-20220927182128835.png)]
高流情况下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IOrHMLdF-1664275921884)(C:\Users\29295\AppData\Roaming\Typora\typora-user-images\image-20220927182135143.png)]

主要功能:

服务降级服务熔断服务限流
服务器忙,请稍后再试,不让客户端等待并立刻返回一个友好提示,fallback;哪些情况会出发降级:程序运行异常超时、服务熔断触发服务降级、线程池/信号量打满也会导致服务降级类比保险丝达到最大服务访问后,直接拒绝访问,拉闸限电,然后调用服务降级的方法并返回友好提示,就是保险丝:服务的降级->进而熔断->恢复调用链路秒杀高并发等操作,严禁一窝蜂的过来拥挤, 大家排队,一秒钟N个,有序进行

熔断是什么?

熔断机制是应对雪崩效应的一种微服务链路保护机制。

当扇出链路的某个微服务出错不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。

当检测到该节点微服务调用响应正常后,恢复调用链路。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dtdjvgM5-1664275921884)(C:\Users\29295\AppData\Roaming\Typora\typora-user-images\image-20220927182851267.png)]

熔断器三种状态?

关闭(Closed):关闭状态(断路器关闭),所有请求都正常访问。

代理类维护了最近调用失败的次数,如果某次调用失败,则使失败次数加1。如果最近失败次数超过了在给定时间内允许失败的阈值,则代理类切换到断开(Open)状态。此时代理开启了一个超时时钟,当该时钟超过了该时间,则切换到半断开(Half-Open)状态。该超时时间的设定是给了系统一次机会来修正导致调用失败的错误。

打开(Open):打开状态(断路器打开),所有请求都会被降级。

Hystix会对请求情况计数,当一定时间内失败请求百分比达到阈值,则触发熔断,断路器会完全关闭。默认失败比例的阈值是50%,请求次数最少不低于20次。

半开(Half Open):半开状态,open状态不是永久的,打开后会进入休眠时间(默认是5S)。

随后断路器会自动进入半开状态。此时会释放1次请求通过,若这个请求是健康的,则会关闭断路器,否则
继续保持打开,再次进行5秒休眠计时。

涉及到断路器的三个重要参数:

  1. 快照时间窗:

    ? 断路器确定是否打开需要统计一些请求和错误数据,而统计的时间范围就是快照时间窗,默认为最近的10秒

  2. 请求总数阀值:

    ? 在快照时间窗内,必须满足请求总数阀值才有资格熔断。默认为20,意味着在10秒内,如果该hystrix命令的调用次数不足20次,即使所有的请求都超时或其他原因失败,断路器都不会打开。

  3. 错误百分比阀值:

    ? 当请求总数在快照时间窗内超过了阀值,比如发生了30次调用,如果在这30次调用中,有15次发生了超时异常,也就是超过50%的错误百分比,在默认设定50%阀值情况下,这时候就会将断路器打开。

代码:

pom

<!--熔断器依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

yml

#启用熔断器
feign:
  hystrix:
    enabled: true

启动类

@EnableCircuitBreaker
@EnableFeignClients
@EnableEurekaClient
@SpringBootApplication
public class ConsumerStudentApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerStudentApplication.class, args);
    }
}

定义降级方法

 @HystrixCommand(fallbackMethod = "timeoutfallback")
    @GetMapping("/timeout")
    public ResponseResult timeout() {
        return studentFeignClient.timeout();
    }

    //定义一个降级方法,和对应的方法的方法签名一致(方法名不同,其它都一样)
	// 上面方法出问题时走这个方法
    public ResponseResult timeoutfallback() {
        return new ResponseResult(500, "ttimeout---fallback", null);
    }

降级方法统一配置【局限性较大,不推荐使用】

@DefaultProperties(defaultFallback = "xxxxfallback")
@RestController
@RequestMapping("/consumerstudent")
public class ConsumerStudent {
    
    @HystrixCommand
    @GetMapping("/timeout")
    public ResponseResult timeout() {
        return studentFeignClient.timeout();
    }
    
    @HystrixCommand
    @GetMapping("/timeok")
    public ResponseResult timeok() {
        return studentFeignClient.timeok();
    }
    
    
    public ResponseResult xxxxfallback() {
        return studentFeignClient.timeout();
    }
}

整合OpenFeign

OpenFeign接口指定对应的降级处理类

package com.woniuxy.consumer.student.feignclient;

import com.woniuxy.common.entity.ResponseResult;
import com.woniuxy.common.entity.Student;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author author
 * @create 2022-09-2022/9/27 11:21
 */
@FeignClient( value = "provider-student",fallback = StudentFeignClientFallback.class)
//@RequestMapping("/student")
public interface StudentFeignClient {

    @GetMapping("/student/{sid}")
    public ResponseResult<Student> getStudentBySid(@PathVariable("sid") int sid);

    @GetMapping("/student/")
    public ResponseResult<List<Student>> getAllStudents();


    @PostMapping("/student/")
    public ResponseResult addStudent(Student student);

    @PostMapping("/student/{pageIndex}/{pageSize}")
    public ResponseResult getStudentsPager(
            @PathVariable("pageIndex") int pageIndex,
            @PathVariable("pageSize") int pageSize,
            @RequestBody Student student);

    @GetMapping("/student/timeout")
    public ResponseResult timeout();

    @GetMapping("/student/timeok")
    public ResponseResult timeok();

}

OpenFeign接口的实现类,定义降级业务逻辑

package com.woniuxy.consumer.student.feignclient;

import com.woniuxy.common.entity.ResponseResult;
import com.woniuxy.common.entity.Student;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author author
 * @create 2022-09-2022/9/27 16:32
 */
@Component
public class StudentFeignClientFallback implements StudentFeignClient {
    @Override
    public ResponseResult<Student> getStudentBySid(int sid) {
        return new ResponseResult(500, "getStudentBySid---fallback", null);
    }

    @Override
    public ResponseResult<List<Student>> getAllStudents() {
        return new ResponseResult(500, "getAllStudents---fallback", null);
    }

    @Override
    public ResponseResult addStudent(Student student) {
        return new ResponseResult(500, "addStudent---fallback", null);
    }

    @Override
    public ResponseResult getStudentsPager(int pageIndex, int pageSize, Student student) {
        return new ResponseResult(500, "getStudentsPager---fallback", null);
    }

    @Override
    public ResponseResult timeout() {
        return new ResponseResult(500, "timeout---fallback", null);
    }

    @Override
    public ResponseResult timeok() {
        return new ResponseResult(500, "timeok---fallback", null);
    }
}
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-09-30 00:38:26  更:2022-09-30 00:40:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年2日历 -2025/2/25 20:23:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码