Eureka + Feign搭建分布式微服务

198 阅读3分钟

Eureka + Feign搭建分布式微服务

项目工程结构

.
├── eureka.server
│   ├── pom.xml
│   └── src
│       └── main
│           ├── java
│           │   └── com
│           │       └── kabai
│           │           └── EurekaServerApplication.java
│           └── resources
│               └── application.properties
├── service.consumer
│   ├── pom.xml
│   └── src
│       └── main
│           ├── java
│           │   └── com
│           │       └── kabai
│           │           ├── ServiceConsumerApplication.java
│           │           ├── client
│           │           │   └── GreetingFeignClient.java
│           │           ├── controller
│           │           │   └── GreetingController.java
│           │           └── service
│           │               └── GreetingService.java
│           └── resources
│               └── application.properties
└── service.provider
    ├── pom.xml
    └── src
        └── main
            ├── java
            │   └── com
            │       └── kabai
            │           ├── ServiceProviderApplication.java
            │           ├── controller
            │           │   └── GreetingController.java
            │           └── service
            └── resources
                └── application.properties

在构建分布式微服务系统时,使用Eureka作为服务注册中心和Feign作为服务之间通信的工具可以极大地简化开发和部署过程。本文将介绍如何使用Eureka和Feign搭建一个简单的微服务架构,包括服务注册中心、服务提供者和服务消费者。

版本

我这里本地配置了两个版本,这里演示项目,需要用到jdk17,maven 3.9.7。

  • jdk17
  • maven 3.9.7
  • Spring Boot 3.3.0
  • Packaging jar
# 配置JDK路径
export JAVA_8_HOME=/Library/Java/JavaVirtualMachines/jdk-1.8.jdk/Contents/Home
export JAVA_17_HOME=/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home

# 默认使用 JDK8
export JAVA_HOME=$JAVA_8_HOME
CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:.

# 配置alias命令动态切换JDK版本
alias jdk8='export JAVA_HOME=$JAVA_8_HOME'
alias jdk17='export JAVA_HOME=$JAVA_17_HOME'

export JAVA_HOME
export CLASSPATH

# 配置maven路径
export MAVEN_3_6_1_HOME=/Users/mac/env/apache-maven-3.6.1
export MAVEN_3_9_7_HOME=/Users/mac/env/apache-maven-3.9.7

# 默认使用 3.6.1
export MAVEN_HOME=$MAVEN_3_6_1_HOME
export PATH=$MAVEN_HOME/bin:$PATH

# 配置alias命令动态切换MAVEN版本
alias mvn3.6='export MAVEN_HOME=$MAVEN_3_6_1_HOME && export PATH=$MAVEN_HOME/bin:${PATH//:$MAVEN_3_9_7_HOME\/bin/}'
alias mvn3.9='export MAVEN_HOME=$MAVEN_3_9_7_HOME && export PATH=$MAVEN_HOME/bin:${PATH//:$MAVEN_3_6_1_HOME\/bin/}'

# 导出MAVEN_HOME和PATH变量
export MAVEN_HOME
export PATH

步骤 1: 创建springboot项目 - 从springboot官网

compressed_WX20240603-224204@2x.png

  • service-provider

compressed_WX20240603-224244@2x.png

  • service-consumer

compressed_WX20240603-224326@2x.png

步骤 2: 设置 Eureka 服务器(eureka-server)

首先,我们需要创建一个Eureka服务器作为服务注册中心。以下是设置Eureka服务器的步骤:

  1. 创建一个新的Spring Boot应用程序
  • @EnableEurekaServer
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);
    }
}
  1. 添加Eureka Server的依赖pom.xml文件中。
  • eureka
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
  • 完整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.0</version>
       <relativePath/>
    </parent>

    <groupId>com.kabai</groupId>
    <artifactId>eureka.server</artifactId>
    <version>1.0.0-RELEASE</version>
    <name>eureka.server</name>
    <description>eureka.server</description>

    <properties>
       <java.version>17</java.version>
       <spring-cloud.version>2023.0.2</spring-cloud.version>
    </properties>

    <dependencies>
       <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
       </dependency>
    </dependencies>
    <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>

    <build>
       <plugins>
          <plugin>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-maven-plugin</artifactId>
          </plugin>
       </plugins>
    </build>

</project>
  1. 配置Eureka服务器的端口和其他属性,如application.properties文件中所示。
server.port=8761
eureka.instance.hostname=localhost
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

logging.level.com.netflix.eureka=DEBUG
logging.level.com.netflix.discovery=DEBUG
logging.level.org.springframework.cloud=DEBUG

步骤 3: 创建服务提供者(service-provider)

接下来,我们创建一个服务提供者,它将向Eureka注册自己的服务,并提供API服务。

  1. 创建一个新的Spring Boot应用程序
  • @EnableDiscoveryClient
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class ServiceProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServiceProviderApplication.class, args);
    }

}
  1. 添加Eureka Discovery Client和Spring Web的依赖pom.xml文件中。
  • eureka-client
<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-web</artifactId>
</dependency>
  • 完整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.0</version>
       <relativePath/>
    </parent>
    <groupId>com.kabai</groupId>
    <artifactId>service.provider</artifactId>
    <version>1.0.0-RELEASE</version>
    <name>service.provider</name>
    <description>service.provider</description>
    <properties>
       <java.version>17</java.version>
       <spring-cloud.version>2023.0.2</spring-cloud.version>
    </properties>
    <dependencies>
       <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
       </dependency>

    </dependencies>
    <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>

    <build>
       <plugins>
          <plugin>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-maven-plugin</artifactId>
          </plugin>
       </plugins>
    </build>

</project>
  1. 配置Eureka客户端连接属性,以连接到Eureka服务器。
spring.application.name=service-provider
server.port=8080
eureka.client.service-url.default-zone=http://localhost:8761/eureka

logging.level.com.netflix.eureka=DEBUG
logging.level.com.netflix.discovery=DEBUG
logging.level.org.springframework.cloud=DEBUG
  1. 创建一个REST控制器,提供API服务。
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingController {

    @GetMapping("/greet")
    public String greet() {
        return "Hello, this is the greeting from Service Provider!";
    }
}

步骤 4: 创建服务消费者(service-consumer)

最后,我们创建一个服务消费者,它将使用Feign来调用服务提供者的API。

  1. 创建一个新的Spring Boot应用程序
  • @EnableDiscoveryClient
  • @EnableFeignClients

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 ServiceConsumerApplication {

    public static void main(String[] args) {
       SpringApplication.run(ServiceConsumerApplication.class, args);
    }

}
  1. 添加OpenFeign、Eureka Discovery Client和Spring Web的依赖pom.xml文件中。
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<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-web</artifactId>
</dependency>
  • 完整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.0</version>
       <relativePath/>
    </parent>
    <groupId>com.kabai</groupId>
    <artifactId>service.consumer</artifactId>
    <version>1.0.0-RELEASE</version>
    <name>service.consumer</name>
    <description>service.consumer</description>
    <properties>
       <java.version>17</java.version>
       <spring-cloud.version>2023.0.2</spring-cloud.version>
    </properties>
    <dependencies>
       <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <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>

    </dependencies>
    <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>

    <build>
       <plugins>
          <plugin>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-maven-plugin</artifactId>
          </plugin>
       </plugins>
    </build>

</project>
  1. 配置Eureka客户端连接属性,以连接到Eureka服务器。
spring.application.name=service-consumer
server.port=8081
eureka.client.service-url.default-zone=http://localhost:8761/eureka

logging.level.com.netflix.eureka=DEBUG
logging.level.com.netflix.discovery=DEBUG
logging.level.org.springframework.cloud=DEBUG
  1. 创建一个Feign客户端接口,用于声明服务提供者的API。
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient(name = "service-provider")
public interface GreetingFeignClient {

    @GetMapping("/greet")
    String greet();
}
  1. 创建一个服务消费者类,注入Feign客户端接口,并使用它来调用服务提供者的API。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class GreetingService {

    private final GreetingFeignClient greetingFeignClient;

    @Autowired
    public GreetingService(GreetingFeignClient greetingFeignClient) {
        this.greetingFeignClient = greetingFeignClient;
    }

    public String callGreetingService() {
        return greetingFeignClient.greet();
    }
}
  1. 暴露一个HTTP接口 来调用callGreetingService方法。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingController {

    private final GreetingService greetingService;

    @Autowired
    public GreetingController(GreetingService greetingService) {
        this.greetingService = greetingService;
    }

    @GetMapping("/call-greeting-service")
    public String callGreetingService() {
        return greetingService.callGreetingService();
    }
}

项目启动

确认服务环境

  • jdk:jdk17
  • maven:3.9.4

依次启动

  • eureka-server
  • service-provider
  • service-consumer

编译、打包、运行

  • eureka-server
jdk17
mvn3.9
mvn clean package
cd target
java -jar eureka.server-1.0.0-RELEASE.jar

compressed_WX20240603-220611@2x.png

  • service.provider
jdk17
mvn3.9
mvn clean package
cd target
java -jar service.provider-1.0.0-RELEASE.jar

compressed_WX20240603-220638@2x.png

  • service.consumer
jdk17
mvn3.9
mvn clean package
cd target
java -jar service.consumer-1.0.0-RELEASE.jar

compressed_WX20240603-220701@2x.png

访问Eureka Dashboard

http://localhost:8761/

compressed_eureka.png

浏览器访问测试接口

http://localhost:8081/call-greeting-service

compressed_WX20240603-221505@2x.png