Eureka Client 服务消费者(调用API接口)(使用OpenFeign)

news/2025/1/7 18:49:39/

一、简介

1. 本文介绍

本文将指导你如何创建一个Spring Boot应用程序作为Eureka Client服务消费者,该服务消费者会从Eureka Server获取服务提供者的列表,并通过该列表与具体的服务提供者进行通信。

在本文中,服务消费者使用 OpenFeign 调用服务提供者的API接口。

2. Eureka Client 介绍

在微服务架构中,服务发现是确保各微服务能够相互通信的关键组件之一。Netflix Eureka是一个广泛使用的开源服务发现工具,它允许服务提供者注册其位置,并让服务消费者发现这些提供者以进行通信。

  • Eureka Client 是一个Java客户端,用于简化与Eureka Server的交互。它可以自动注册自身到Eureka Server上,并定期发送心跳来更新其状态。
  • 服务提供者是实际提供业务逻辑的服务,它们会将自己注册到Eureka Server上。
  • 服务消费者是从Eureka Server获取服务提供者的列表,并通过该列表与具体的服务提供者进行通信。

3. 依赖版本

Spring Boot:3.4.0
Spring Boot Cloud:2024.0.0

二、创建 Eureka Client 服务消费者

1. 创建一个新的Spring Boot项目

可以通过Spring Initializr (https://start.spring.io/) 来快速创建一个新的Spring Boot项目。在创建时,请确保选择以下依赖项:

  • Spring Web:为了能够使用Spring MVC来构建Web应用程序。
  • Eureka Client:这个依赖项会引入所有必要的库来创建Eureka Client
  • OpenFeign:这个依赖项会引入OpenFeign客户端来进行服务间的通信。

2. 依赖

如果你手动创建了项目,你需要确保你的构建文件中包含了 Eureka Client 的依赖。

(1)Spring Cloud BOM

使用 spring-cloud-dependencies BOM来确保所有Spring Cloud相关依赖的版本一致性。

    <properties><spring-cloud.version>2024.0.0</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>

(2)Eureka Client 依赖

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

(3)OpenFeign 依赖

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

(4)POM完整示例

<?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.4.0</version><relativePath/></parent><groupId>com.example</groupId><artifactId>hello-eureka-client-consumer</artifactId><version>1.0.0</version><name>hello-eureka-client-consumer</name><description>Eureka Client 服务消费者(调用API接口)(使用OpenFeign)</description><properties><java.version>21</java.version><spring-cloud.version>2024.0.0</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><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></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.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><annotationProcessorPaths><path><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></path></annotationProcessorPaths></configuration></plugin><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>

3. 默认配置启动(不可用于生产)

Spring Cloud Netflix Eureka Client有默认的行为。如果没有指定Eureka服务器的位置,它会尝试连接到http://localhost:8761/eureka/。这是Eureka Server的默认地址和端口。

注意:在实际生产中,必须配置正确的 Eureka Server 地址,以及其他相关配置。

(1)启动日志


(2)Eureka Server管理界面

4. 配置Eureka Server的基本设置(application.yml)

spring:application:name: hello-eureka-client-consumerserver:port: 8082 # 应用程序的端口eureka:client:service-url:defaultZone: http://localhost:8761/eureka/ # Eureka Server的地址register-with-eureka: false # 是否注册自身到Eureka Serverfetch-registry: true # 是否从Eureka Server获取注册表信息instance:prefer-ip-address: true # 使用IP地址而非主机名进行注册instance-id: ${spring.application.name}:${random.value} # 唯一实例ID

5. 启动成功

6. 无需注册服务

根据上诉配置,不会将自身注册到 Eureka Server, 只会拉取服务提供者的列表。

可以通过访问Eureka Server的管理界面(默认是http://localhost:8761)来查看效果:

三、启动日志分析

  .   ____          _            __ _ _/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/  ___)| |_)| | | | | || (_| |  ) ) ) )'  |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot ::                (v3.4.0)2024-12-14T22:11:48.389+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] c.c.HelloEurekaClientConsumerApplication : Starting HelloEurekaClientConsumerApplication using Java 21.0.1 with PID 13732 (E:\eureka\hello-eureka-client-consumer\target\classes started by SongGuanxun in E:\eureka\hello-eureka-client-consumer)
2024-12-14T22:11:48.396+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] c.c.HelloEurekaClientConsumerApplication : No active profile set, falling back to 1 default profile: "default"
2024-12-14T22:11:51.130+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] o.s.cloud.context.scope.GenericScope     : BeanFactory id=08b0b462-971a-34b2-9c92-b11b1c919e3f
2024-12-14T22:11:52.190+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8082 (http)
2024-12-14T22:11:52.246+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2024-12-14T22:11:52.248+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.33]
2024-12-14T22:11:52.449+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-12-14T22:11:52.453+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3875 ms
2024-12-14T22:11:54.282+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] DiscoveryClientOptionalArgsConfiguration : Eureka HTTP Client uses RestTemplate.
2024-12-14T22:11:54.410+08:00  WARN 13732 --- [hello-eureka-client-consumer] [           main] iguration$LoadBalancerCaffeineWarnLogger : Spring Cloud LoadBalancer is currently working with the default cache. While this cache implementation is useful for development and tests, it's recommended to use Caffeine cache in production.You can switch to using Caffeine cache, by adding it and org.springframework.cache.caffeine.CaffeineCacheManager to the classpath.
2024-12-14T22:11:54.567+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] o.s.c.n.eureka.InstanceInfoFactory       : Setting initial instance status as: STARTING
2024-12-14T22:11:54.683+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] com.netflix.discovery.DiscoveryClient    : Initializing Eureka in region us-east-1
2024-12-14T22:11:54.706+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] c.n.d.s.r.aws.ConfigClusterResolver      : Resolving eureka endpoints via configuration
2024-12-14T22:11:54.755+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] com.netflix.discovery.DiscoveryClient    : Disable delta property : false
2024-12-14T22:11:54.755+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] com.netflix.discovery.DiscoveryClient    : Single vip registry refresh property : null
2024-12-14T22:11:54.755+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] com.netflix.discovery.DiscoveryClient    : Force full registry fetch : false
2024-12-14T22:11:54.755+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] com.netflix.discovery.DiscoveryClient    : Application is null : false
2024-12-14T22:11:54.755+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] com.netflix.discovery.DiscoveryClient    : Registered Applications size is zero : true
2024-12-14T22:11:54.756+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] com.netflix.discovery.DiscoveryClient    : Application version is -1: true
2024-12-14T22:11:54.756+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] com.netflix.discovery.DiscoveryClient    : Getting all instance registry info from the eureka server
2024-12-14T22:11:55.944+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] com.netflix.discovery.DiscoveryClient    : The response status is 200
2024-12-14T22:11:55.948+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] com.netflix.discovery.DiscoveryClient    : Not registering with Eureka server per configuration
2024-12-14T22:11:55.953+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] com.netflix.discovery.DiscoveryClient    : Discovery Client initialized at timestamp 1734185515951 with initial instances count: 1
2024-12-14T22:11:55.964+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] o.s.c.n.e.s.EurekaServiceRegistry        : Registering application HELLO-EUREKA-CLIENT-CONSUMER with eureka with status UP
2024-12-14T22:11:56.027+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8082 (http) with context path '/'
2024-12-14T22:11:56.029+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] .s.c.n.e.s.EurekaAutoServiceRegistration : Updating port to 8082
2024-12-14T22:11:56.068+08:00  INFO 13732 --- [hello-eureka-client-consumer] [           main] c.c.HelloEurekaClientConsumerApplication : Started HelloEurekaClientConsumerApplication in 9.235 seconds (process running for 11.57)
2024-12-14T22:16:54.777+08:00  INFO 13732 --- [hello-eureka-client-consumer] [rap-executor-%d] c.n.d.s.r.aws.ConfigClusterResolver      : Resolving eureka endpoints via configuration
2024-12-14T22:21:54.788+08:00  INFO 13732 --- [hello-eureka-client-consumer] [rap-executor-%d] c.n.d.s.r.aws.ConfigClusterResolver      : Resolving eureka endpoints via configuration

从你提供的日志中,我们可以看到几个关键的日志条目,表明Eureka Client已经成功地从Eureka Server获取了服务提供者的列表。以下是相关的日志信息及其解释:

  1. 尝试初始化Eureka客户端

    • 2024-12-14T22:11:54.683+08:00 INFO 13732 --- [hello-eureka-client-consumer] [ main] com.netflix.discovery.DiscoveryClient : Initializing Eureka in region us-east-1
    • 这一行表示Eureka Client正在初始化,并指定了区域us-east-1(这通常是默认值,可能与实际地理位置无关)。
  2. 获取所有实例注册表信息

    • 2024-12-14T22:11:54.756+08:00 INFO 13732 --- [hello-eureka-client-consumer] [ main] com.netflix.discovery.DiscoveryClient : Getting all instance registry info from the eureka server
    • 这一行显示Eureka Client正准备从Eureka Server获取所有已注册的服务实例信息。
  3. 响应状态码为200

    • 2024-12-14T22:11:55.944+08:00 INFO 13732 --- [hello-eureka-client-consumer] [ main] com.netflix.discovery.DiscoveryClient : The response status is 200
    • HTTP 200状态码意味着请求成功,即Eureka Client成功地从Eureka Server获取到了数据。
  4. 发现客户端初始化完成,初始实例数量为1

    • 2024-12-14T22:11:55.953+08:00 INFO 13732 --- [hello-eureka-client-consumer] [ main] com.netflix.discovery.DiscoveryClient : Discovery Client initialized at timestamp 1734185515951 with initial instances count: 1
    • 这一行明确指出Eureka Client已经初始化完成,并且它在启动时就已经发现了1个服务实例。这个数字是重要的,因为它确认了至少有一个服务实例被成功拉取到本地缓存。
  5. 不向Eureka服务器注册自身

    • 2024-12-14T22:11:55.948+08:00 INFO 13732 --- [hello-eureka-client-consumer] [ main] com.netflix.discovery.DiscoveryClient : Not registering with Eureka server per configuration
    • 根据你的配置,这条日志确认了该应用不会将自己注册到Eureka Server,这是预期的行为。
  6. Tomcat启动和应用程序启动

    • 2024-12-14T22:11:56.027+08:00 INFO 13732 --- [hello-eureka-client-consumer] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8082 (http) with context path '/'
    • 2024-12-14T22:11:56.068+08:00 INFO 13732 --- [hello-eureka-client-consumer] [ main] c.c.HelloEurekaClientConsumerApplication : Started HelloEurekaClientConsumerApplication in 9.235 seconds (process running for 11.57)
    • 这两行日志说明Tomcat服务器已经在8082端口启动,而且Spring Boot应用程序也已经成功启动。

根据上述日志,可以确定你的Eureka Client已经成功地从Eureka Server那里获取到了服务提供者的列表,并且在启动时检测到了至少一个服务实例。如果你的应用程序需要依赖这些服务,那么现在应该可以正常工作并与其他服务进行交互。如果需要进一步验证,可以通过编程方式检查DiscoveryClient或通过访问Eureka Dashboard来确认服务的可用性。

四、OpenFeign调用接口

1. 启用OpenFeign

在 Spring Boot 应用程序中启用 OpenFeign,可以通过在启动类上添加 @EnableFeignClients 注解来实现:

package com.example.hello.eureka.client.consumer;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;@EnableFeignClients
@SpringBootApplication
public class HelloEurekaClientConsumerApplication {public static void main(String[] args) {SpringApplication.run(HelloEurekaClientConsumerApplication.class, args);}}

注意:如果不添加 @EnableFeignClients 注解,会报错。
报错原因: Spring Boot 应用程序在尝试初始化 userController Bean 时遇到了问题。具体来说,它无法找到类型为 com.example.hello.eureka.client.consumer.feign.UserFeignClient 的合格 Bean 来满足 userController 构造函数的依赖。

2. 定义 Feign Client 接口

定义一个接口来代表客户端,并使用 @FeignClient 注解来配置它;@FeignClient 注解中的 name 属性指定了要调用的 服务名

package com.example.hello.eureka.client.consumer.feign;import com.example.hello.eureka.client.consumer.core.model.PageQuery;
import com.example.hello.eureka.client.consumer.core.model.UserVo;
import com.example.hello.eureka.client.consumer.core.response.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.web.bind.annotation.GetMapping;import java.util.List;@FeignClient(name = "hello-eureka-client-provider", path = "/users")
public interface UserFeignClient {@GetMappingResult<List<UserVo>> listUsers(@SpringQueryMap PageQuery pageQuery);}

3. 使用 Feign Client

在你的应用程序中,你可以通过注入 Feign Client 接口来使用它。例如:

package com.example.hello.eureka.client.consumer.web.user.controller;import com.example.hello.eureka.client.consumer.core.model.PageQuery;
import com.example.hello.eureka.client.consumer.core.model.UserVo;
import com.example.hello.eureka.client.consumer.core.response.Result;
import com.example.hello.eureka.client.consumer.feign.UserFeignClient;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
@RequestMapping("/users")
@RequiredArgsConstructor
public class UserController {private final UserFeignClient userFeignClient;@GetMapping// @Operation(summary = "查询用户列表")public Result<List<UserVo>> listUsers(PageQuery pageQuery) {return userFeignClient.listUsers(pageQuery);}}

在这个示例中,UserController 控制器通过构造函数注入了 UserFeignClient,并使用它来调用远程服务。

4. 服务消费者(调用API接口)

服务提供者的API接口:

服务消费者(调用API接口)(使用OpenFeign):

五、启动日志分析(添加OpenFeign后)

SpringBoot项目,集成了EurekaClient和OpenFeign,请分析一下启动日志

D:\Java\jdk-21\bin\java.exe -javaagent:D:\IDEA\lib\idea_rt.jar=2889:D:\IDEA\bin -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath E:\eureka\hello-eureka-client-consumer\target\classes;D:\maven\repository\org\springframework\boot\spring-boot-starter-web\3.4.0\spring-boot-starter-web-3.4.0.jar;D:\maven\repository\org\springframework\boot\spring-boot-starter\3.4.0\spring-boot-starter-3.4.0.jar;D:\maven\repository\org\springframework\boot\spring-boot\3.4.0\spring-boot-3.4.0.jar;D:\maven\repository\org\springframework\boot\spring-boot-autoconfigure\3.4.0\spring-boot-autoconfigure-3.4.0.jar;D:\maven\repository\org\springframework\boot\spring-boot-starter-logging\3.4.0\spring-boot-starter-logging-3.4.0.jar;D:\maven\repository\ch\qos\logback\logback-classic\1.5.12\logback-classic-1.5.12.jar;D:\maven\repository\ch\qos\logback\logback-core\1.5.12\logback-core-1.5.12.jar;D:\maven\repository\org\apache\logging\log4j\log4j-to-slf4j\2.24.1\log4j-to-slf4j-2.24.1.jar;D:\maven\repository\org\apache\logging\log4j\log4j-api\2.24.1\log4j-api-2.24.1.jar;D:\maven\repository\org\slf4j\jul-to-slf4j\2.0.16\jul-to-slf4j-2.0.16.jar;D:\maven\repository\jakarta\annotation\jakarta.annotation-api\2.1.1\jakarta.annotation-api-2.1.1.jar;D:\maven\repository\org\yaml\snakeyaml\2.3\snakeyaml-2.3.jar;D:\maven\repository\org\springframework\boot\spring-boot-starter-json\3.4.0\spring-boot-starter-json-3.4.0.jar;D:\maven\repository\com\fasterxml\jackson\core\jackson-databind\2.18.1\jackson-databind-2.18.1.jar;D:\maven\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.18.1\jackson-datatype-jdk8-2.18.1.jar;D:\maven\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.18.1\jackson-datatype-jsr310-2.18.1.jar;D:\maven\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.18.1\jackson-module-parameter-names-2.18.1.jar;D:\maven\repository\org\springframework\boot\spring-boot-starter-tomcat\3.4.0\spring-boot-starter-tomcat-3.4.0.jar;D:\maven\repository\org\apache\tomcat\embed\tomcat-embed-core\10.1.33\tomcat-embed-core-10.1.33.jar;D:\maven\repository\org\apache\tomcat\embed\tomcat-embed-el\10.1.33\tomcat-embed-el-10.1.33.jar;D:\maven\repository\org\apache\tomcat\embed\tomcat-embed-websocket\10.1.33\tomcat-embed-websocket-10.1.33.jar;D:\maven\repository\org\springframework\spring-web\6.2.0\spring-web-6.2.0.jar;D:\maven\repository\org\springframework\spring-beans\6.2.0\spring-beans-6.2.0.jar;D:\maven\repository\io\micrometer\micrometer-observation\1.14.1\micrometer-observation-1.14.1.jar;D:\maven\repository\io\micrometer\micrometer-commons\1.14.1\micrometer-commons-1.14.1.jar;D:\maven\repository\org\springframework\spring-webmvc\6.2.0\spring-webmvc-6.2.0.jar;D:\maven\repository\org\springframework\spring-aop\6.2.0\spring-aop-6.2.0.jar;D:\maven\repository\org\springframework\spring-context\6.2.0\spring-context-6.2.0.jar;D:\maven\repository\org\springframework\spring-expression\6.2.0\spring-expression-6.2.0.jar;D:\maven\repository\org\springframework\cloud\spring-cloud-starter-netflix-eureka-client\4.2.0\spring-cloud-starter-netflix-eureka-client-4.2.0.jar;D:\maven\repository\org\springframework\cloud\spring-cloud-starter\4.2.0\spring-cloud-starter-4.2.0.jar;D:\maven\repository\org\springframework\cloud\spring-cloud-context\4.2.0\spring-cloud-context-4.2.0.jar;D:\maven\repository\org\bouncycastle\bcprov-jdk18on\1.78.1\bcprov-jdk18on-1.78.1.jar;D:\maven\repository\org\springframework\cloud\spring-cloud-netflix-eureka-client\4.2.0\spring-cloud-netflix-eureka-client-4.2.0.jar;D:\maven\repository\org\apache\httpcomponents\client5\httpclient5\5.4.1\httpclient5-5.4.1.jar;D:\maven\repository\org\apache\httpcomponents\core5\httpcore5\5.3.1\httpcore5-5.3.1.jar;D:\maven\repository\org\apache\httpcomponents\core5\httpcore5-h2\5.3.1\httpcore5-h2-5.3.1.jar;D:\maven\repository\com\netflix\eureka\eureka-client\2.0.4\eureka-client-2.0.4.jar;D:\maven\repository\com\thoughtworks\xstream\xstream\1.4.20\xstream-1.4.20.jar;D:\maven\repository\io\github\x-stream\mxparser\1.2.2\mxparser-1.2.2.jar;D:\maven\repository\xmlpull\xmlpull\1.1.3.1\xmlpull-1.1.3.1.jar;D:\maven\repository\jakarta\ws\rs\jakarta.ws.rs-api\3.1.0\jakarta.ws.rs-api-3.1.0.jar;D:\maven\repository\jakarta\inject\jakarta.inject-api\2.0.1\jakarta.inject-api-2.0.1.jar;D:\maven\repository\com\netflix\spectator\spectator-api\1.7.3\spectator-api-1.7.3.jar;D:\maven\repository\org\slf4j\slf4j-api\2.0.16\slf4j-api-2.0.16.jar;D:\maven\repository\org\apache\httpcomponents\httpclient\4.5.3\httpclient-4.5.3.jar;D:\maven\repository\org\apache\httpcomponents\httpcore\4.4.16\httpcore-4.4.16.jar;D:\maven\repository\commons-codec\commons-codec\1.17.1\commons-codec-1.17.1.jar;D:\maven\repository\commons-configuration\commons-configuration\1.10\commons-configuration-1.10.jar;D:\maven\repository\commons-lang\commons-lang\2.6\commons-lang-2.6.jar;D:\maven\repository\com\fasterxml\jackson\core\jackson-annotations\2.18.1\jackson-annotations-2.18.1.jar;D:\maven\repository\com\fasterxml\jackson\core\jackson-core\2.18.1\jackson-core-2.18.1.jar;D:\maven\repository\com\netflix\netflix-commons\netflix-eventbus\0.3.0\netflix-eventbus-0.3.0.jar;D:\maven\repository\com\netflix\netflix-commons\netflix-infix\0.3.0\netflix-infix-0.3.0.jar;D:\maven\repository\commons-jxpath\commons-jxpath\1.3\commons-jxpath-1.3.jar;D:\maven\repository\joda-time\joda-time\2.3\joda-time-2.3.jar;D:\maven\repository\org\antlr\antlr-runtime\3.4\antlr-runtime-3.4.jar;D:\maven\repository\org\antlr\stringtemplate\3.2.1\stringtemplate-3.2.1.jar;D:\maven\repository\antlr\antlr\2.7.7\antlr-2.7.7.jar;D:\maven\repository\com\google\guava\guava\33.3.1-jre\guava-33.3.1-jre.jar;D:\maven\repository\com\google\guava\failureaccess\1.0.2\failureaccess-1.0.2.jar;D:\maven\repository\com\google\guava\listenablefuture\9999.0-empty-to-avoid-conflict-with-guava\listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar;D:\maven\repository\org\checkerframework\checker-qual\3.43.0\checker-qual-3.43.0.jar;D:\maven\repository\com\google\errorprone\error_prone_annotations\2.28.0\error_prone_annotations-2.28.0.jar;D:\maven\repository\com\google\j2objc\j2objc-annotations\3.0.0\j2objc-annotations-3.0.0.jar;D:\maven\repository\com\google\code\gson\gson\2.11.0\gson-2.11.0.jar;D:\maven\repository\com\netflix\servo\servo-core\0.5.3\servo-core-0.5.3.jar;D:\maven\repository\org\apache\commons\commons-math\2.2\commons-math-2.2.jar;D:\maven\repository\javax\annotation\javax.annotation-api\1.2\javax.annotation-api-1.2.jar;D:\maven\repository\org\codehaus\jettison\jettison\1.5.4\jettison-1.5.4.jar;D:\maven\repository\org\springframework\cloud\spring-cloud-starter-loadbalancer\4.2.0\spring-cloud-starter-loadbalancer-4.2.0.jar;D:\maven\repository\org\springframework\cloud\spring-cloud-loadbalancer\4.2.0\spring-cloud-loadbalancer-4.2.0.jar;D:\maven\repository\io\projectreactor\reactor-core\3.7.0\reactor-core-3.7.0.jar;D:\maven\repository\org\reactivestreams\reactive-streams\1.0.4\reactive-streams-1.0.4.jar;D:\maven\repository\io\projectreactor\addons\reactor-extra\3.5.2\reactor-extra-3.5.2.jar;D:\maven\repository\org\springframework\boot\spring-boot-starter-cache\3.4.0\spring-boot-starter-cache-3.4.0.jar;D:\maven\repository\org\springframework\spring-context-support\6.2.0\spring-context-support-6.2.0.jar;D:\maven\repository\com\stoyanr\evictor\1.0.0\evictor-1.0.0.jar;D:\maven\repository\org\springframework\cloud\spring-cloud-starter-openfeign\4.2.0\spring-cloud-starter-openfeign-4.2.0.jar;D:\maven\repository\org\springframework\cloud\spring-cloud-openfeign-core\4.2.0\spring-cloud-openfeign-core-4.2.0.jar;D:\maven\repository\io\github\openfeign\feign-form-spring\13.5\feign-form-spring-13.5.jar;D:\maven\repository\io\github\openfeign\feign-form\13.5\feign-form-13.5.jar;D:\maven\repository\commons-fileupload\commons-fileupload\1.5\commons-fileupload-1.5.jar;D:\maven\repository\commons-io\commons-io\2.11.0\commons-io-2.11.0.jar;D:\maven\repository\org\springframework\cloud\spring-cloud-commons\4.2.0\spring-cloud-commons-4.2.0.jar;D:\maven\repository\org\springframework\security\spring-security-crypto\6.4.1\spring-security-crypto-6.4.1.jar;D:\maven\repository\io\github\openfeign\feign-core\13.5\feign-core-13.5.jar;D:\maven\repository\io\github\openfeign\feign-slf4j\13.5\feign-slf4j-13.5.jar;D:\maven\repository\org\projectlombok\lombok\1.18.36\lombok-1.18.36.jar;D:\maven\repository\org\springframework\spring-core\6.2.0\spring-core-6.2.0.jar;D:\maven\repository\org\springframework\spring-jcl\6.2.0\spring-jcl-6.2.0.jar com.example.hello.eureka.client.consumer.HelloEurekaClientConsumerApplication.   ____          _            __ _ _/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/  ___)| |_)| | | | | || (_| |  ) ) ) )'  |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot ::                (v3.4.0)2024-12-17T22:42:52.524+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] c.c.HelloEurekaClientConsumerApplication : Starting HelloEurekaClientConsumerApplication using Java 21.0.1 with PID 15160 (E:\eureka\hello-eureka-client-consumer\target\classes started by SongGuanxun in E:\eureka\hello-eureka-client-consumer)
2024-12-17T22:42:52.533+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] c.c.HelloEurekaClientConsumerApplication : No active profile set, falling back to 1 default profile: "default"
2024-12-17T22:42:55.789+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] o.s.cloud.context.scope.GenericScope     : BeanFactory id=f26524b8-9327-3e68-843b-15ac62a4b99a
2024-12-17T22:42:56.794+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8082 (http)
2024-12-17T22:42:56.858+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2024-12-17T22:42:56.858+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.33]
2024-12-17T22:42:57.041+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-12-17T22:42:57.044+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4222 ms
2024-12-17T22:42:57.816+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] o.s.c.openfeign.FeignClientFactoryBean   : For 'hello-eureka-client-provider' URL not provided. Will try picking an instance via load-balancing.
2024-12-17T22:42:59.642+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] DiscoveryClientOptionalArgsConfiguration : Eureka HTTP Client uses RestTemplate.
2024-12-17T22:42:59.765+08:00  WARN 15160 --- [hello-eureka-client-consumer] [           main] iguration$LoadBalancerCaffeineWarnLogger : Spring Cloud LoadBalancer is currently working with the default cache. While this cache implementation is useful for development and tests, it's recommended to use Caffeine cache in production.You can switch to using Caffeine cache, by adding it and org.springframework.cache.caffeine.CaffeineCacheManager to the classpath.
2024-12-17T22:42:59.886+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] o.s.c.n.eureka.InstanceInfoFactory       : Setting initial instance status as: STARTING
2024-12-17T22:42:59.988+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] com.netflix.discovery.DiscoveryClient    : Initializing Eureka in region us-east-1
2024-12-17T22:43:00.001+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] c.n.d.s.r.aws.ConfigClusterResolver      : Resolving eureka endpoints via configuration
2024-12-17T22:43:00.028+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] com.netflix.discovery.DiscoveryClient    : Disable delta property : false
2024-12-17T22:43:00.029+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] com.netflix.discovery.DiscoveryClient    : Single vip registry refresh property : null
2024-12-17T22:43:00.029+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] com.netflix.discovery.DiscoveryClient    : Force full registry fetch : false
2024-12-17T22:43:00.030+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] com.netflix.discovery.DiscoveryClient    : Application is null : false
2024-12-17T22:43:00.030+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] com.netflix.discovery.DiscoveryClient    : Registered Applications size is zero : true
2024-12-17T22:43:00.030+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] com.netflix.discovery.DiscoveryClient    : Application version is -1: true
2024-12-17T22:43:00.030+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] com.netflix.discovery.DiscoveryClient    : Getting all instance registry info from the eureka server
2024-12-17T22:43:01.327+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] com.netflix.discovery.DiscoveryClient    : The response status is 200
2024-12-17T22:43:01.333+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] com.netflix.discovery.DiscoveryClient    : Not registering with Eureka server per configuration
2024-12-17T22:43:01.340+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] com.netflix.discovery.DiscoveryClient    : Discovery Client initialized at timestamp 1734446581335 with initial instances count: 1
2024-12-17T22:43:01.351+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] o.s.c.n.e.s.EurekaServiceRegistry        : Registering application HELLO-EUREKA-CLIENT-CONSUMER with eureka with status UP
2024-12-17T22:43:01.411+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8082 (http) with context path '/'
2024-12-17T22:43:01.413+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] .s.c.n.e.s.EurekaAutoServiceRegistration : Updating port to 8082
2024-12-17T22:43:01.444+08:00  INFO 15160 --- [hello-eureka-client-consumer] [           main] c.c.HelloEurekaClientConsumerApplication : Started HelloEurekaClientConsumerApplication in 10.67 seconds (process running for 12.872)
2024-12-17T22:44:56.875+08:00  INFO 15160 --- [hello-eureka-client-consumer] [nio-8082-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2024-12-17T22:44:56.876+08:00  INFO 15160 --- [hello-eureka-client-consumer] [nio-8082-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2024-12-17T22:44:56.879+08:00  INFO 15160 --- [hello-eureka-client-consumer] [nio-8082-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 3 ms

根据你提供的Spring Boot项目的启动日志,我们可以分析出以下信息:

  1. Spring Boot版本:

    • 项目使用的是Spring Boot v3.4.0。
  2. Java版本:

    • 项目运行在Java 21.0.1上。
  3. 应用名称与启动方式:

    • 应用名称为HelloEurekaClientConsumerApplication,它位于com.c包下。
    • 该应用是通过IDE或命令行(例如Maven的spring-boot:run)启动的,而不是作为打包好的JAR文件执行。启动路径是E:\eureka\hello-eureka-client-consumer
  4. 激活配置文件:

    • 没有设置任何活动的profile,所以默认使用了名为"default"的profile。
  5. Web容器:

    • 使用的是嵌入式的Tomcat服务器,监听HTTP端口8082。
  6. OpenFeign:

    • Feign客户端被用来调用名为hello-eureka-client-provider的服务,但是没有提供具体的URL。这意味着它将依赖于服务发现(如Eureka)来定位服务实例。
  7. Eureka Client:

    • 应用程序初始化了一个Eureka客户端,并尝试连接到Eureka服务器进行注册和获取其他服务的信息。
    • Eureka HTTP客户端使用的是RestTemplate。
    • 日志显示应用程序成功从Eureka服务器获取了所有实例的注册表信息,并且响应状态码为200。
    • 应用程序最终以状态“UP”注册到了Eureka服务器。
  8. LoadBalancer警告:

    • 存在一个警告信息指出Spring Cloud LoadBalancer正在使用默认缓存实现。在生产环境中,可以使用Caffeine缓存,通过添加相关依赖来替换默认缓存。
  9. 启动时间:

    • 应用程序总共花费了大约10.67秒完成启动过程,而整个进程(包括JVM启动等)用了约12.872秒。
  10. DispatcherServlet初始化:

    • 在第一次HTTP请求到来时(大约1分钟后的22:44:56),DispatcherServlet被初始化,这表明这是懒加载模式,即只有当第一个请求到达时才会初始化Servlet。

综上所述,你的Spring Boot应用是一个Eureka客户端,它集成了OpenFeign用于服务间通信,并且成功地启动并注册到了Eureka服务器。同时,应用已经准备好接受HTTP请求,因为Tomcat服务器已经在指定的端口上启动。对于生产环境,你应该考虑解决关于LoadBalancer缓存的警告,确保使用更高效的缓存机制如Caffeine。

eureka_endpoints_via_configuration_495">六、日志解析:Resolving eureka endpoints via configuration

启动后的日志,请分析一下

2024-12-17T22:48:00.043+08:00  INFO 15160 --- [hello-eureka-client-consumer] [rap-executor-%d] c.n.d.s.r.aws.ConfigClusterResolver      : Resolving eureka endpoints via configuration
2024-12-17T22:53:00.054+08:00  INFO 15160 --- [hello-eureka-client-consumer] [rap-executor-%d] c.n.d.s.r.aws.ConfigClusterResolver      : Resolving eureka endpoints via configuration
2024-12-17T22:58:00.066+08:00  INFO 15160 --- [hello-eureka-client-consumer] [rap-executor-%d] c.n.d.s.r.aws.ConfigClusterResolver      : Resolving eureka endpoints via configuration
2024-12-17T23:03:00.080+08:00  INFO 15160 --- [hello-eureka-client-consumer] [rap-executor-%d] c.n.d.s.r.aws.ConfigClusterResolver      : Resolving eureka endpoints via configuration

你提供的日志显示,每隔大约5分钟,ConfigClusterResolver类就会尝试解析Eureka的端点信息。具体来说,这些日志条目表明Eureka客户端正在定期检查其配置以确定Eureka服务器的地址。这种行为是正常的,因为Eureka客户端会周期性地刷新其对Eureka服务器的认知,确保它总是拥有最新的服务注册表信息。

1. 分析

  1. 定时任务:

    • 日志中的时间戳(如22:48:00, 22:53:00, 22:58:00, 23:03:00)显示了这个操作是以固定的时间间隔(约5分钟)发生的。这是Eureka客户端的一个内置机制,用于定期更新和验证与Eureka服务器的连接信息。
  2. 线程池:

    • [rap-executor-%d]表示这些任务是由一个名为rap-executor的线程池执行的。%d是一个占位符,代表线程池中的不同线程编号。这表明Eureka客户端使用了专门的线程池来处理这些后台任务,以避免阻塞主线程或其他关键操作。
  3. ConfigClusterResolver:

    • 这个类负责解析Eureka服务器的端点信息。根据你的YAML配置,service-url.defaultZone已经指定了Eureka服务器的地址为http://localhost:8761/eureka/。因此,ConfigClusterResolver的任务就是确认这个配置是否仍然有效,并且如果有多个Eureka服务器(形成集群),它还会解析所有可用的服务器地址。
  4. 日志级别:

    • 所有这些日志条目的级别都是INFO,这意味着它们只是提供信息性的消息,不表示任何错误或警告。如果你没有看到其他更高级别的日志(如WARNERROR),那么可以认为Eureka客户端在正常工作,能够成功解析并连接到Eureka服务器。

2. 结论

  • 正常行为: 你看到的日志是Eureka客户端正常工作的表现。它定期检查Eureka服务器的地址,确保其拥有的服务注册表是最新的。

  • 无须担心: 由于这些日志只是信息性的,而且频率也是预期中的(通常默认是每5分钟一次),所以你不需要为此感到担忧。除非你在应用中遇到了与Eureka相关的连接问题或服务发现失败的问题,否则这些日志不会影响系统的正常运行。

  • 优化建议:

    • 如果你发现这些日志过于频繁或者希望减少日志量,你可以考虑调整Eureka客户端的配置,例如修改eureka.client.registry-fetch-interval-seconds属性来改变获取注册表信息的频率。不过,默认设置通常是经过优化的,适合大多数场景。
    • 如果你不打算使用Eureka集群(即只有一个Eureka服务器),并且希望减少不必要的日志输出,可以将eureka.client.fetch-registry设置为false,但这将阻止客户端从Eureka服务器获取服务注册表信息,只适用于你确实不需要这项功能的情况。

总之,目前的日志表明Eureka客户端正在按照预期工作,定期检查并解析Eureka服务器的端点信息。如果你的应用程序和服务发现机制都正常工作,那么这些日志是可以忽略的。

七、Eureka配置分析

上文的注册到了Eureka服务器,什么意思?
按照本文的配置,当前的Eureka配置,应该不会将注册自身到Eureka Server。

你提到的配置确实表明了当前的应用程序不会将自己注册到Eureka Server,但仍然会从Eureka Server获取服务注册表信息。让我们具体解释一下这些配置项以及它们的作用:

1. Eureka Client 配置解析

eureka:client:service-url:defaultZone: http://localhost:8761/eureka/ # Eureka Server的地址register-with-eureka: false # 是否注册自身到Eureka Serverfetch-registry: true # 是否从Eureka Server获取注册表信息instance:prefer-ip-address: true # 使用IP地址而非主机名进行注册instance-id: ${spring.application.name}:${random.value} # 唯一实例ID
  • service-url.defaultZone: 指定了Eureka服务器的位置。在这个例子中,它指向本地运行的Eureka服务器,端口为8761。

  • register-with-eureka: false: 这个属性设置为false意味着该应用程序不会作为服务提供者注册到Eureka服务器。换句话说,其他服务不会通过Eureka找到这个应用,因为它的实例信息没有被添加到Eureka的服务注册表中。

  • fetch-registry: true: 尽管该应用不注册自己,但它仍然可以从Eureka服务器拉取最新的服务注册表信息。这意味着它可以发现并调用其他已经注册到Eureka的服务(例如,通过OpenFeign)。这是非常有用的,特别是对于那些只作为消费者的角色,不需要公开自己的API给其他服务调用的情况。

  • instance.prefer-ip-address: true: 当这个属性被设置为true时,Eureka客户端在注册时会使用其IP地址而不是主机名。这有助于避免DNS解析问题,并确保即使在复杂的网络环境中也能正确地定位服务。

  • instance.instance-id: 定义了服务实例的唯一标识符。这里使用了${spring.application.name}和一个随机值来创建一个唯一的实例ID,这对于区分同一应用的不同实例特别有用,尤其是在集群环境中。

2. “注册到了Eureka服务器”的含义

当一个服务被说成“注册到了Eureka服务器”,通常指的是该服务作为一个服务提供者向Eureka服务器报告了自己的存在。这样,其他服务就可以通过Eureka找到并调用它。注册过程包括发送心跳请求以维持其在线状态,并提供一些元数据(如主机、端口、健康检查URL等),以便其他服务能够与之通信。

然而,在你的配置中,由于register-with-eureka被设置为了false,所以这个特定的应用程序不会作为一个服务提供者注册到Eureka服务器。它只能作为服务消费者,利用Eureka的服务发现功能来查找并调用其他已注册的服务。如果你希望这个应用也能够被其他服务发现和调用,你需要将register-with-eureka设置为true


http://www.ppmy.cn/news/1561032.html

相关文章

第五届神经网络、信息与通信工程国际学术会议(NNICE 2025)

在线投稿&#xff1a;学术会议-学术交流征稿-学术会议在线-艾思科蓝 征稿主题&#xff1a; 神经网络 机器人控制 优化组合 知识工程 人工智能 逻辑程序设计 人机交互 深度学习 信号处理 信息提取 自然语言推论 信号与信息处理 信息管理与集成 实时信号处理与应用、 DSP应用 图…

STM32单片机芯片与内部52 I2C 数据手册 寄存器

目录 一、I2C寄存器 1、控制寄存器 1(I2C_CR1) 2、控制寄存器 2(I2C_CR2) 3、自身地址寄存器 1(I2C_OAR1) 4、自身地址寄存器 2(I2C_OAR2) 5、数据寄存器(I2C_DR) 6、状态寄存器 1(I2C_SR1) 7、状态寄存器 2 (I2C_SR2) 8、时钟控制寄存器(I2C_CCR) 9、TRISE寄存器(I2…

【Vim Masterclass 笔记08】第 6 章:Vim 中的文本变换及替换操作 + S06L20:文本的插入、变更、替换,以及合并操作

文章目录 Section 6&#xff1a;Transforming and Substituting TextS06L21 Inserting, Changing, Replacing, and Joining1 定位到行首非空字符&#xff0c;并启用插入模式2 在紧挨光标的下一个字符位置启动插入模式3 定位到一行末尾&#xff0c;并启用插入模式4 定位到光标的…

Docker入门常用命令总结

1.从远程仓库拉取一个纯净的镜像 docker pull docker .io/centos 2.创建并进入容器&#xff08;左外右内&#xff09; docker run --name xxx -dit 镜像id&#xff08;镜像名称:Tag&#xff09; /bin/bash 【参数必须放在镜像ID之前】 -i 让Docker分配一个伪终端&#xff0c;并…

C# OpenCV机器视觉:非刚性物体跟踪

在实验室的一方小天地里&#xff0c;阳光像是被赋予了生命&#xff0c;透过窗户&#xff0c;调皮地在阿强的桌面上跳跃、嬉戏&#xff0c;洒下一片片暖融融的金黄光影。阿强坐在桌前&#xff0c;双眼凝视着眼前那台宛如沉睡巨兽般的高分辨率摄像头&#xff0c;以及一旁静静矗立…

samba服务 使用

SAMBA服务 访问安装 http://www.samba.org/ #模拟window共享[rootvm ~]# yum -y install samba [rootvm ~]# systemctl start smb [rootvm ~]# ss -antlp| grep smb LISTEN 0 50 *:445 *:* users:(("smbd",pid20155,fd36)) LISTEN 0…

JSON结构快捷转XML结构API集成指南

JSON结构快捷转XML结构API集成指南 引言 在当今的软件开发世界中&#xff0c;数据交换格式的选择对于系统的互操作性和效率至关重要。JSON&#xff08;JavaScript Object Notation&#xff09;和XML&#xff08;eXtensible Markup Language&#xff09;是两种广泛使用的数据表…

Java SpringBoot使用Apache POI导入导出Excel文件

点击下载《Java SpringBoot使用Apache POI导入导出Excel文件(源代码)》 1. Apache POI 简介 Apache POI 是一个强大的 Java 库&#xff0c;用于处理 Microsoft Office 文档&#xff0c;包括 Excel 文件&#xff08;.xls 和 .xlsx&#xff09;。在 Java Spring Boot 项目中&am…