Eureka+Spring Cloud OpenFeign 实现默认的负载均衡与Fallback(回退)

1. 项目总体结构

解释:eureKaServer是服务注册中心,eureKaProvider8001eureKaProvider8002是生产者,用来模拟负载均衡,eurekaConsumer是消费者,pom.xml是父类工程的pom文件。  

1.1 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>org.example</groupId>
    <artifactId>spring-feign</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
        <module>eurekaServer</module>
        <module>eurekaProvider8001</module>
        <module>eurekaProvider8002</module>
        <module>eurekaConsumer</module>
    </modules>

    <properties>
        <spring-cloud.version>2023.0.3</spring-cloud.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <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.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2. eurekaServerm模块

2.1 项目结构

2.2 pom.xml 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.example</groupId>
        <artifactId>spring-feign</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>eurekaServer</artifactId>
    <packaging>jar</packaging>
    <name>eurekaServer</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>
</project>

2.3  eurekaServerApplication.java

package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

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

2.4 application.yaml

server:
  port: 8761  # Eureka Server的端口

spring:
  application:
    name: eureka-server  # 应用名称

eureka:
  instance:
    prefer-ip-address: true  # 使用IP地址而不是hostname进行通信
    hostname: eureka-server  # 主机名
    lease-renewal-interval-in-seconds: 10  # Eureka客户端发送心跳的时间间隔
    lease-expiration-duration-in-seconds: 30  # Eureka客户端租约到期时间
  client:
    register-with-eureka: false  # 是否将自己注册到Eureka Server
    fetch-registry: false  # 是否获取注册信息
  server:
    enable-self-preservation: true  # 启用自我保护机制
    renewal-threshold-update-interval-ms: 60000  # 更新续约阈值的时间间隔

注:当你启动该模块时,请访问http://localhost:8761/而不是http://localhost:8761/eureka,出现以下页面即说明服务注册中心搭建成功。

 3. eurekaProvider8001模块

3.1 项目结构

3.2 pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.example</groupId>
        <artifactId>spring-feign</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <artifactId>eurekaProvider8001</artifactId>
    <packaging>jar</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>
    </dependencies>
</project>

3.3 数据库相关操作 

-- 创建数据库
create database es;
-- 使用数据库
use es;
-- 创建 blog 表
CREATE TABLE blog
(
    id             INT AUTO_INCREMENT PRIMARY KEY, -- id 字段,使用 INT 类型,并设置为自增主键
    title          TEXT,                           -- title 字段,使用 TEXT 类型来存储大文本数据
    content        TEXT,                           -- content 字段,使用 TEXT 类型来存储大文本数据
    author         VARCHAR(255),                   -- author 字段,使用 VARCHAR(255) 类型来存储字符串,适用于关键字类型(精确匹配)
    published_date DATE                            -- publishedDate 字段,使用 DATE 类型来存储日期数据,支持范围查询和排序操作
);

-- 插入20数据
INSERT INTO `blog` (`title`, `content`, `author`, `published_date`)
VALUES ('探索区块链的实际应用', '区块链技术不仅限于数字货币,其在供应链管理中的应用同样革命性。', '张三', '2022-07-15'),
       ('家庭园艺的基础知识', '简单介绍如何在家里开始你的园艺活动,包括基本的园艺工具和技巧。', '李四', '2022-06-20'),
       ('智能家居技术的前景', '随着科技的进步,智能家居逐渐走进我们的生活,带来了便利和安全。', '王五', '2022-08-01'),
       ('最新科技趋势大揭秘', '2023年科技行业的五大趋势,包括AI的进步和物联网的发展。', '赵六', '2022-05-11'),
       ('健康饮食的误区', '讨论常见的健康饮食误区,帮助你制定更科学的饮食计划。', '钱七', '2022-04-22'),
       ('如何选择跑鞋', '正确的跑鞋可以提升你的跑步体验,减少受伤的风险,了解如何选择适合你的跑鞋。', '孙八',
        '2022-07-08'),
       ('提升时间管理能力', '高效的时间管理技巧可以让你事半功倍,这里有一些实用的建议。', '周九', '2022-03-30'),
       ('深入理解云计算', '云计算如何改变企业 IT 架构和成本效益,以及如何选择合适的云服务提供商。', '吴十', '2022-08-15'),
       ('精致咖啡的冲泡技巧', '从咖啡豆的选择到冲泡方法,一步步教你制作精致的咖啡。', '郑十一', '2022-07-18'),
       ('职场软技能的重要性', '软技能对职业发展同样重要,了解哪些软技能是你职业生涯的加分项。', '王十二', '2022-06-06'),
       ('程序员的学习路径', '如何成为一名成功的程序员?这里有一些关于学习路径和资源的建议。', '李十三', '2022-05-20'),
       ('数据分析的基本工具', '初学者如何入门数据分析,这些工具和技巧你不能错过。', '张十四', '2022-04-07'),
       ('运动对心理健康的好处', '运动不仅可以改善你的身体健康,还能提升你的心理状态。', '赵十五', '2022-03-15'),
       ('数字营销的最佳实践', '掌握数字营销的关键技巧,让你的业务在竞争激烈的市场中脱颖而出。', '周十六', '2022-08-10'),
       ('城市园林的设计原则', '城市园林设计不仅要美观,还应考虑生态和可持续性。', '吴十七', '2022-09-09'),
       ('远程工作的生产力技巧', '远程工作成为常态,如何保持高效?这些技巧可以帮到你。', '钱十八', '2022-02-28'),
       ('宠物照护的基本常识', '拥有宠物之前,了解这些基本的照护知识是必须的。', '孙十九', '2022-01-10'),
       ('探索古代中国的建筑艺术', '中国古代建筑不仅雄伟,每一砖一瓦都蕴含深厚的文化意义。', '周二十', '2022-10-01'),
       ('电影摄影的艺术技巧', '电影摄影不同于普通摄影,了解其背后的艺术和技术。', '赵二十一', '2022-11-11'),
       ('创新教育方法的探索', '传统教育方法已不适应新时代,探索更有效的教育创新方法。', '王二十二', '2022-12-12');

3.4 EurekaProviderApplication8001.java

package org.example;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

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

3.5 Blog.java

package org.example.entity;

import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;

import java.time.LocalDate;

@Getter
@Setter
@Table(name = "blog")
@Entity
public class Blog {
    @Id
    @Column(name = "id", nullable = false)
    private Integer id;

    @Lob
    @Column(name = "title")
    private String title;

    @Lob
    @Column(name = "content")
    private String content;

    @Column(name = "author")
    private String author;

    @Column(name = "published_date")
    private LocalDate publishedDate;
}

3.6 BlogRepository.java

package org.example.repository;

import org.example.entity.Blog;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface BlogRepository extends JpaRepository<Blog,Long> {

}

3.7 BlogController.java

package org.example.controller;

import org.example.entity.Blog;
import org.example.repository.BlogRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@RestController
@RequestMapping("/blogs")
public class BlogController {

    @Autowired
    private BlogRepository blogRepository;

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

    // 模拟读超时
    @GetMapping
    public ResponseEntity<?> getAllBlogs(){
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        List<Blog> blogs = blogRepository.findAll();
            return ResponseEntity.ok(blogs);
    }


    // 根据ID获取博客文章,并返回端口信息
    @GetMapping("/{id}")
    public ResponseEntity<Map<String, Object>> getBlogById(@PathVariable Integer id) {
        Optional<Blog> blog = blogRepository.findById(Long.valueOf(id));
        if (blog.isPresent()) {
            Map<String, Object> response = new HashMap<>();
            response.put("blog", blog.get());
            response.put("port", port);
            return ResponseEntity.ok(response);
        } else {
            return ResponseEntity.notFound().build();
        }
    }
}

3.8 GlobalExceptionHandler.java

package org.example.excepyion;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collections;
import java.util.Map;

@ControllerAdvice
@RestController
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public final ResponseEntity<Map<String, String>> handleAllExceptions(Exception ex) {
        Map<String, String> response = Collections.singletonMap("error", "An unexpected error occurred: " + ex.getMessage());
        return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

3.9 application.yml

# 设置服务器端口
server:
  port: 8001

# Spring应用的基本配置
spring:
  # 设置Spring Boot应用的名称,这将在Eureka服务注册中心使用
  application:
    name: eureka-provider

  # 配置数据库连接
  datasource:
    url: jdbc:mysql://localhost:3306/es?useSSL=false&serverTimezone=UTC  # 数据库连接URL,包含数据库名称、SSL使用和服务器时区配置
    username: root  # 数据库用户名
    password: 123456  # 数据库密码
    driver-class-name: com.mysql.cj.jdbc.Driver  # JDBC驱动类

  # JPA相关配置
  jpa:
    hibernate:
      ddl-auto: update  # Hibernate的DDL自动执行策略,这里设置为update,即自动更新数据库结构
    show-sql: true  # 是否在控制台显示SQL语句
    properties:
      hibernate:
        format_sql: true  # 是否格式化显示SQL语句

# Eureka客户端配置
eureka:
  instance:
    prefer-ip-address: true  # 优先使用IP地址而非主机名注册到Eureka服务器
  client:
    register-with-eureka: true  # 是否将当前应用注册到Eureka服务注册中心
    fetch-registry: true  # 是否从Eureka服务注册中心获取注册信息
    service-url:
      defaultZone: http://localhost:8761/eureka/  # 指定Eureka服务注册中心的地址

 注:如果你启动该模块,访问http://localhost:8761/会出现以下内容说明注册到服务注册中心成功。

4. eurekaProvider8002模块

4.1 项目结构

注:8002模块和8001模块几乎一致,不同点在于端口不同,还有模拟的错误不同,以下是不同文件的完整代码。

4.2 EurekaProviderApplication8002.java

package org.example;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

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

注:区分不同的启动名称。

4.3 BlogController.java

package org.example.controller;

import org.example.entity.Blog;
import org.example.repository.BlogRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@RestController
@RequestMapping("/blogs")
public class BlogController {

    @Autowired
    private BlogRepository blogRepository;

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

    // 模拟自定义异常
    @GetMapping
    public ResponseEntity<?> getAllBlogs(){
            int i=1/0;
            List<Blog> blogs = blogRepository.findAll();
            return ResponseEntity.ok(blogs);
    }

    // 根据ID获取博客文章,并返回端口信息
    @GetMapping("/{id}")
    public ResponseEntity<Map<String, Object>> getBlogById(@PathVariable Integer id) {
        Optional<Blog> blog = blogRepository.findById(Long.valueOf(id));
        if (blog.isPresent()) {
            Map<String, Object> response = new HashMap<>();
            response.put("blog", blog.get());
            response.put("port", port);
            return ResponseEntity.ok(response);
        } else {
            return ResponseEntity.notFound().build();
        }
    }
}

注:不同点这个是模拟自定义异常。

4.4 application.yml

server:
  port: 8002
spring:
  application:
    name: eureka-provider

  datasource:
    url: jdbc:mysql://localhost:3306/es
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
    properties:
      hibernate:
        format_sql: true

eureka:
  instance:
    prefer-ip-address: true
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
    register-with-eureka: true
    fetch-registry: true

注:该不同点在端口:8002。

        如果你启动该模块,访问http://localhost:8761/会出现以下内容说明注册到服务注册中心成功。 

 5. eurekaConsumer模块

5.1 项目结构

5.2 pom.xml 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.example</groupId>
        <artifactId>spring-feign</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <artifactId>eurekaConsumer</artifactId>
    <packaging>jar</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

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

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

    </dependencies>
</project>

5.3 EurekaConsumerApplication.java

package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

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

5.4 Blog.java

package org.example.entity;

import lombok.Getter;
import lombok.Setter;

import java.time.LocalDate;
@Getter
@Setter
public class Blog {

    private Integer id;

    private String title;

    private String content;

    private String author;

    private LocalDate publishedDate;
}

5.5 ProviderClient.java

package org.example.client;
import org.example.utils.ProviderFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.context.annotation.Primary;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.Map;
@FeignClient(name = "eureka-provider",fallbackFactory = ProviderFallbackFactory.class)
@Primary
public interface ProviderClient {

    //模拟回退 超时或系统异常
    @GetMapping("/blogs")
    ResponseEntity<?> getAllBlogs();

    //模拟负载均衡
    @GetMapping("/blogs/{id}")
    ResponseEntity<Map<String, Object>> getBlogById(@PathVariable Integer id);

}

 解释:

1. @FeignClient 注解的使用
name: 用于指定远程服务的名称,这个名称应与Eureka服务注册中心中注册的服务名完全一致。fallbackFactory: 指定了一个用于生成fallback实例的工厂类,当远程服务调用失败时,例如超时或服务不可达,会使用此 fallback 逻辑。

2. URL匹配
确保Feign客户端接口中的方法与生产者服务的端点URL完全匹配。例如,如果生产者服务中有一个处理GET请求的端点/blogs/{id},则客户端接口也必须使用相同的URI模式。

3. HTTP方法
Feign客户端的每个方法必须使用正确的HTTP方法注解(如@GetMapping, @PostMapping, @PutMapping, @DeleteMapping等),以匹配生产者服务端点的设计。

4. 请求和响应数据结构
请求参数:确保任何路径变量(@PathVariable)、查询参数(@RequestParam)或请求体(@RequestBody)的使用与生产者服务的API定义一致。

响应处理:客户端方法的返回类型应该能够正确处理生产者服务的响应数据结构。通常使用ResponseEntity<T>可以更灵活地处理包括HTTP状态码和响应体在内的完整HTTP响应。


5. Header和Cookie传递
如果生产者服务需要特定的HTTP头或Cookie来处理请求,Feign客户端必须能够正确发送这些信息。可以使用@RequestHeader或@CookieValue来传递这些数据。

6. 异常处理
理解生产者可能抛出的异常类型和相关的HTTP状态码,并在Feign客户端中相应地进行处理,特别是当使用fallback或fallbackFactory处理服务降级时。

5.6 ProviderFallbackFactory.java

package org.example.utils;

import feign.FeignException;
import org.example.client.ProviderClient;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.Map;

@Component
public class ProviderFallbackFactory implements FallbackFactory<ProviderClient> {

    @Override
    public ProviderClient create(Throwable cause) {
        return new ProviderClient() {

            @Override
            public ResponseEntity<?> getAllBlogs() {
                // 检查具体的异常原因
                if (cause instanceof FeignException) {
                    FeignException feignException = (FeignException) cause;
                    return new ResponseEntity<>(Collections.singletonMap("Fallback response", "Producer service is unavailable. Reason: " + feignException.getMessage()), HttpStatus.NOT_FOUND);
                }
                return new ResponseEntity<>(Collections.singletonMap("Fallback response", "Producer service is unavailable."), HttpStatus.NOT_FOUND);
            }

            @Override
            public ResponseEntity<Map<String, Object>> getBlogById(Integer id) {
                return null;
            }
        };
    }
}

5.7 ConsumerController.java

package org.example.controller;

import org.example.client.ProviderClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;
import java.util.concurrent.CompletableFuture;

@RestController
@RequestMapping("/consume")
public class ConsumerController {

    @Autowired
    private ProviderClient providerClient;

    @GetMapping
    public CompletableFuture<ResponseEntity<?>> callBackendService() {
        return CompletableFuture.supplyAsync(() -> {
            return providerClient.getAllBlogs();
        });
    }

    @GetMapping("/{id}")
    public ResponseEntity<Map<String, Object>> consume(@PathVariable Integer id) {
        return providerClient.getBlogById(id);
    }
}

5.8 application.yaml

# 设置Spring Boot应用服务的运行端口
server:
  port: 8080

# Spring应用的基本配置
spring:
  application:
    name: eureka-consumer  # 定义Spring Boot应用的名称,此名称将用于Eureka服务注册中心

  # OpenFeign客户端的全局配置
  cloud:
    openfeign:
      client:
        config:
          default:
            connectTimeout: 1000  # 定义Feign客户端的连接超时时间(毫秒)
            readTimeout: 500  # 定义Feign客户端的读取超时时间(毫秒)

      # 配置断路器,以增强服务的容错能力
      circuitbreaker:
        enabled: true  # 启用断路器功能

# Eureka客户端配置
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/  # 定义连接到Eureka服务器的服务URL
    register-with-eureka: true  # 是否将当前应用注册到Eureka服务注册中心
    fetch-registry: true  # 是否从Eureka服务注册中心获取注册信息

 注: 如果你启动该模块,访问http://localhost:8761/会出现以下内容说明注册到服务注册中心成功。 

6. 测试验证 (Postman)

6.1 负载均衡

注: 访问的是端口8001。

 

注:再次访问,访问的是端口8002,使用的是默认的负载均衡策略。 

6.1 CircuitBreaker 回退

6.1.1 读超时

6.1.2 自定义异常1/0

 6.1.3 连接超时

        前提条件:两个生产者都宕机了,手动进行模拟把两个生产者关机。

7. 总结

        通过eureka服务注册中心,讲生产者和消费者注册到服务注册中心,再结合OpenFeign实现简单的负载均衡和熔断回退处理。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值