一、简介
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获取了服务提供者的列表。以下是相关的日志信息及其解释:
-
尝试初始化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
(这通常是默认值,可能与实际地理位置无关)。
-
获取所有实例注册表信息:
-
响应状态码为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获取到了数据。
-
发现客户端初始化完成,初始实例数量为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个服务实例。这个数字是重要的,因为它确认了至少有一个服务实例被成功拉取到本地缓存。
-
不向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,这是预期的行为。
-
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项目的启动日志,我们可以分析出以下信息:
-
Spring Boot版本:
- 项目使用的是Spring Boot v3.4.0。
-
Java版本:
- 项目运行在Java 21.0.1上。
-
应用名称与启动方式:
-
激活配置文件:
- 没有设置任何活动的profile,所以默认使用了名为"default"的profile。
-
Web容器:
- 使用的是嵌入式的Tomcat服务器,监听HTTP端口8082。
-
OpenFeign:
- Feign客户端被用来调用名为
hello-eureka-client-provider
的服务,但是没有提供具体的URL。这意味着它将依赖于服务发现(如Eureka)来定位服务实例。
- Feign客户端被用来调用名为
-
Eureka Client:
- 应用程序初始化了一个Eureka客户端,并尝试连接到Eureka服务器进行注册和获取其他服务的信息。
- Eureka HTTP客户端使用的是RestTemplate。
- 日志显示应用程序成功从Eureka服务器获取了所有实例的注册表信息,并且响应状态码为200。
- 应用程序最终以状态“UP”注册到了Eureka服务器。
-
LoadBalancer警告:
- 存在一个警告信息指出Spring Cloud LoadBalancer正在使用默认缓存实现。在生产环境中,可以使用Caffeine缓存,通过添加相关依赖来替换默认缓存。
-
启动时间:
- 应用程序总共花费了大约10.67秒完成启动过程,而整个进程(包括JVM启动等)用了约12.872秒。
-
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. 分析
-
定时任务:
- 日志中的时间戳(如
22:48:00
,22:53:00
,22:58:00
,23:03:00
)显示了这个操作是以固定的时间间隔(约5分钟)发生的。这是Eureka客户端的一个内置机制,用于定期更新和验证与Eureka服务器的连接信息。
- 日志中的时间戳(如
-
线程池:
[rap-executor-%d]
表示这些任务是由一个名为rap-executor
的线程池执行的。%d
是一个占位符,代表线程池中的不同线程编号。这表明Eureka客户端使用了专门的线程池来处理这些后台任务,以避免阻塞主线程或其他关键操作。
-
ConfigClusterResolver
类:- 这个类负责解析Eureka服务器的端点信息。根据你的YAML配置,
service-url.defaultZone
已经指定了Eureka服务器的地址为http://localhost:8761/eureka/
。因此,ConfigClusterResolver
的任务就是确认这个配置是否仍然有效,并且如果有多个Eureka服务器(形成集群),它还会解析所有可用的服务器地址。
- 这个类负责解析Eureka服务器的端点信息。根据你的YAML配置,
-
日志级别:
- 所有这些日志条目的级别都是
INFO
,这意味着它们只是提供信息性的消息,不表示任何错误或警告。如果你没有看到其他更高级别的日志(如WARN
、ERROR
),那么可以认为Eureka客户端在正常工作,能够成功解析并连接到Eureka服务器。
- 所有这些日志条目的级别都是
2. 结论
-
正常行为: 你看到的日志是Eureka客户端正常工作的表现。它定期检查Eureka服务器的地址,确保其拥有的服务注册表是最新的。
-
无须担心: 由于这些日志只是信息性的,而且频率也是预期中的(通常默认是每5分钟一次),所以你不需要为此感到担忧。除非你在应用中遇到了与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
。