Spring Boot2.x 集成 Eureka 与 Feign

发布时间 2023-12-27 21:30:38作者: 夏秋初

参考

注意事项

  1. Feign 集成了 Hystrix 与 Ribbon,可以配置负载均衡(默认轮询)和熔断降级等功能。
  2. Eureka 支持多注册中心、多服务提供者和多消费者,本文仅单注册中心、单服务提供者和单消费者。
  3. Eureka 注册中心可以直接访问,可以通过添加安全库实现账号密码登录。
  4. Feign 支持授权与认证。

环境

环境 版本 说明
windows 10
vs code 1.85.1
Spring Boot Extension Pack v0.2.1 vscode插件
Extension Pack for Java v0.25.15 vscode插件
JDK 11
Springboot 2.3.12.RELEASE
mybatis-spring-boot-starter 2.1.4 mvn依赖
spring-cloud-dependencies Hoxton.SR12 mvn依赖
spring-cloud-starter-netflix-eureka-client 未设置 mvn依赖
spring-cloud-starter-netflix-eureka-server 未设置 mvn依赖
spring-cloud-starter-openfeign 未设置 mvn依赖
Apache Maven 3.8.6

正文

本文章 demo 项目为多模块项目,分为:registry(注册中心)、provider(提供者)、consumer(消费者)和 common (公共模块)。
多模块的模块间注册到父模块,父模块导入子模块,子模块导入子模块等事项不再赘述。

步骤

  1. 根目录准备
    1. 在项目根目录的 pom.xml dependencyManagement/dependencies 中指定 Spring Boot、Spring Cloud 与四个子模块的版本号。
  2. registry 子模块(注册中心)
    1. pom.xml 引入依赖 spring-cloud-starter-netflix-eureka-server
      	<dependencies>
      	 <dependency>
      			<groupId>org.springframework.boot</groupId>
      			<artifactId>spring-boot-starter</artifactId>
      		</dependency>
      		<dependency>
      			<groupId>org.springframework.boot</groupId>
      			<artifactId>spring-boot-starter-test</artifactId>
      			<scope>test</scope>
      		</dependency>
      
      		<dependency>
      			<groupId>org.springframework.boot</groupId>
      			<artifactId>spring-boot-starter-web</artifactId>
      		</dependency>
      
      		<dependency>
      			<groupId>org.springframework.boot</groupId>
      			<artifactId>spring-boot-devtools</artifactId>
      			<scope>runtime</scope>
      			<optional>true</optional>
      		</dependency>
      		<dependency>
      			<groupId>org.projectlombok</groupId>
      			<artifactId>lombok</artifactId>
      			<optional>true</optional>
      		</dependency>
      		<dependency>
      			<groupId>com.xiaqiuchu</groupId>
      			<artifactId>common</artifactId>
      		</dependency>
      		<!-- 引入eureka -->
      		<dependency>
      			<groupId>org.springframework.cloud</groupId>
      			<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
      		</dependency>
      	</dependencies>
      
    2. 入口文件添加 @EnableEurekaServer 注解。
      package com.xiaqiuchu.registry;
      
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
      
      /**
       * 参考 https://www.cnblogs.com/yxth/p/10845640.html , https://juejin.cn/post/6973680096011878407
       */
      @EnableEurekaServer
      @SpringBootApplication
      public class RegistryApplication {
      	public static void main(String[] args) {
      		SpringApplication.run(RegistryApplication.class, args);
      	}
      
      }
      
      
    3. 配置文件 application.properties 配置项目名称、注册中心相关配置。
      # 应用服务 WEB 访问端口
      server.port=8081
      # 定义项目名称
      spring.application.name=registry
      
      # eureka.instance.hostname,instance-id,prefer-ip-address的作用及区别 https://blog.csdn.net/m0_37959155/article/details/122521406
      
      
      # eureka: Connection refused: connect stacktrace=com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: connect
      # 解决 https://blog.csdn.net/Shnywe/article/details/123682758
      
      # 无需向注册中心注册(本模块是注册中心)
      eureka.client.register-with-eureka=false
      # 不拉取服务信息(本模块是注册中心)
      eureka.client.fetch-registry=false
      # 客户端在注册时使用自己的IP而不是主机名
      eureka.instance.prefer-ip-address=true
      # eureka.instance.instance-id=${spring.cloud.ip-address}:${spring.application.name}:${server.port}
      
  3. provider 子模块(服务提供者)
    1. pom.xml 引入 spring-cloud-starter-netflix-eureka-client 依赖
      <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</artifactId>
      		</dependency>
      		<dependency>
      			<groupId>org.springframework.boot</groupId>
      			<artifactId>spring-boot-starter-test</artifactId>
      			<scope>test</scope>
      		</dependency>
      
      		<dependency>
      			<groupId>org.springframework.boot</groupId>
      			<artifactId>spring-boot-starter-web</artifactId>
      		</dependency>
      
      		<dependency>
      			<groupId>org.springframework.boot</groupId>
      			<artifactId>spring-boot-devtools</artifactId>
      			<scope>runtime</scope>
      			<optional>true</optional>
      		</dependency>
      		<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
      		<dependency>
      			<groupId>mysql</groupId>
      			<artifactId>mysql-connector-java</artifactId>
      			<version>8.0.28</version>
      		</dependency>
      		 <dependency>
      			<groupId>org.mybatis.spring.boot</groupId>
      			<artifactId>mybatis-spring-boot-starter</artifactId>
      			<version>2.1.4</version>
      		</dependency>
      		<dependency>
      			<groupId>org.projectlombok</groupId>
      			<artifactId>lombok</artifactId>
      			<optional>true</optional>
      		</dependency>
      		<dependency>
      			<groupId>com.xiaqiuchu</groupId>
      			<artifactId>common</artifactId>
      		</dependency>
      	</dependencies>
      
    2. 入口文件添加 @EnableEurekaClient 注解
      package com.xiaqiuchu.provider;
      
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
      
      @EnableEurekaClient
      @SpringBootApplication
      public class ProviderApplication {
      	public static void main(String[] args) {
      		SpringApplication.run(ProviderApplication.class, args);
      	}
      
      }
      
      
    3. 创建接口 student/ping
      package com.xiaqiuchu.provider.controller;
      
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      import org.springframework.web.bind.annotation.GetMapping;
      
      @RestController
      @RequestMapping("/student")
      public class StudentController {
      
      	@GetMapping("ping")
      	public String ping() {
      		return "HELLO WORLD";
      	}
      }
      
    4. 配置文件 application.properties 配置项目名称、注册中心相关配置。
      # 应用服务 WEB 访问端口
      server.port=8082
      # 定义项目名称
      spring.application.name=student-teacher-provider
      #注册中心路径,表示我们向这个注册中心注册服务,如果向多个注册中心注册,用“,”进行分隔
      eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8081/eureka
      #心跳间隔5s,默认30s。每一个服务配置后,心跳间隔和心跳超时时间会被保存在server端,不同服务的心跳频率可能不同,server端会根据保存的配置来分别探活
      eureka.instance.lease-renewal-interval-in-seconds=5
      #心跳超时时间10s,默认90s。从client端最后一次发出心跳后,达到这个时间没有再次发出心跳,表示服务不可用,将它的实例从注册中心移除
      eureka.instance.lease-expiration-duration-in-seconds=10
      
  4. consumer 子模块(消费者)
    1. pom.xml 引入 spring-cloud-starter-netflix-eureka-client 依赖
      <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.boot</groupId>
      		<artifactId>spring-boot-starter</artifactId>
      	</dependency>
      	<dependency>
      		<groupId>org.springframework.boot</groupId>
      		<artifactId>spring-boot-starter-test</artifactId>
      		<scope>test</scope>
      	</dependency>
      
      	<dependency>
      		<groupId>org.springframework.boot</groupId>
      		<artifactId>spring-boot-starter-web</artifactId>
      	</dependency>
      
      	<dependency>
      		<groupId>org.springframework.boot</groupId>
      		<artifactId>spring-boot-devtools</artifactId>
      		<scope>runtime</scope>
      		<optional>true</optional>
      	</dependency>
      	<dependency>
      		<groupId>org.projectlombok</groupId>
      		<artifactId>lombok</artifactId>
      		<optional>true</optional>
      	</dependency>
      	<dependency>
      		<groupId>com.xiaqiuchu</groupId>
      		<artifactId>common</artifactId>
      	</dependency>
      </dependencies>
      
    2. 入口文件添加注解 @EnableFeignClients@EnableEurekaClient
      package com.xiaqiuchu.consumer;
      
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
      import org.springframework.cloud.openfeign.EnableFeignClients;
      
      @EnableFeignClients
      @EnableEurekaClient
      @SpringBootApplication
      public class ConsumerApplication {
      	public static void main(String[] args) {
      		SpringApplication.run(ConsumerApplication.class, args);
      	}
      
      }
      
      
    3. 创建 \consumer\src\main\java\com\xiaqiuchu\consumer\service\StudentService.java 接口类。
      package com.xiaqiuchu.consumer.service;
      
      import org.springframework.cloud.openfeign.FeignClient;
      import org.springframework.web.bind.annotation.GetMapping;
      // 服务名
      @FeignClient(value = "STUDENT-TEACHER-PROVIDER")
      public interface  StudentService {
      	// 服务地址,不支持在类上添加 @RequestMapping 注解!
      	@GetMapping("/student/ping")
      	public String ping();
      }
      
      
    4. 配置文件 application.properties 配置项目名称、注册中心相关配置。
      # 应用服务 WEB 访问端口
      server.port=8080
      # 定义项目名称
      spring.application.name=student-teacher-consumer
      #注册中心路径,表示我们向这个注册中心注册服务,如果向多个注册中心注册,用“,”进行分隔
      eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8081/eureka
      #心跳间隔5s,默认30s。每一个服务配置后,心跳间隔和心跳超时时间会被保存在server端,不同服务的心跳频率可能不同,server端会根据保存的配置来分别探活
      eureka.instance.lease-renewal-interval-in-seconds=5
      #心跳超时时间10s,默认90s。从client端最后一次发出心跳后,达到这个时间没有再次发出心跳,表示服务不可用,将它的实例从注册中心移除
      eureka.instance.lease-expiration-duration-in-seconds=10
      
  5. common 子模块(公共模块),存放公共文件,如数据库实体等。

测试

  1. 启动所有服务。
  2. 访问 registry(注册中心)网页管理中心 http://127.0.0.1:8081/ ,本文设置的端口号为:8081。

如果 Instances currently registered with Eureka 中没有应用,可以先等一会。

image