项目场景:

最近在使用Spring Cloud的Eureka服务时,遇到了一个线上问题:Eureka启动一直报错,提示Network level connection to peer localhost;retrying after delay。通过一番排查,发现问题的根本原因竟然是配置文件中的eureka defaultZone未生效,而造成这一情况的直接原因是spring.profiles未正确激活。

ERROR 3144 --- [et_localhost-12] c.n.e.cluster.ReplicationTaskProcessor : Network level connection to peer localhost; retrying after delay

com.sun.jersey.api.client.ClientHandlerException: org.apache.http.conn.ConnectTimeoutException: Connect to localhost:8761 timed out

at com.sun.jersey.client.apache4.ApacheHttpClient4Handler.handle(ApacheHttpClient4Handler.java:187) ~[jersey-apache-client4-1.19.1.jar:1.19.1]

at com.netflix.eureka.cluster.DynamicGZIPContentEncodingFilter.handle(DynamicGZIPContentEncodingFilter.java:48) ~[eureka-core-1.4.10.jar:1.4.10]

at com.netflix.discovery.EurekaIdentityHeaderFilter.handle(EurekaIdentityHeaderFilter.java:27) ~[eureka-client-1.4.10.jar:1.4.10]

at com.sun.jersey.api.client.Client.handle(Client.java:652) ~[jersey-client-1.19.1.jar:1.19.1]

at com.sun.jersey.api.client.WebResource.handle(WebResource.java:682) ~[jersey-client-1.19.1.jar:1.19.1]

at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74) ~[jersey-client-1.19.1.jar:1.19.1]

at com.sun.jersey.api.client.WebResource$Builder.post(WebResource.java:570) ~[jersey-client-1.19.1.jar:1.19.1]

at com.netflix.eureka.transport.JerseyReplicationClient.submitBatchUpdates(JerseyReplicationClient.java:116) ~[eureka-core-1.4.10.jar:1.4.10]

at com.netflix.eureka.cluster.ReplicationTaskProcessor.process(ReplicationTaskProcessor.java:71) ~[eureka-core-1.4.10.jar:1.4.10]

at com.netflix.eureka.util.batcher.TaskExecutors$BatchWorkerRunnable.run(TaskExecutors.java:187) [eureka-core-1.4.10.jar:1.4.10]

at java.lang.Thread.run(Thread.java:745) [na:1.8.0_92]

Caused by: org.apache.http.conn.ConnectTimeoutException: Connect to localhost:8761 timed out

✨问题描述

在Eureka配置文件中,我们正常地配置了eureka defaultZone,但在启动应用后却一直报错,无法连接到Eureka服务器。初步怀疑是网络问题,但通过排查发现并非如此。最终,我们锁定了问题根源——spring.profiles未正确激活。

当时配置文件

spring:

application:

name: prod_eureka

server:

port: 8810

security:

basic:

enabled: true

user:

name: admin

password: 1q2w3e4r5t6y7U

eureka:

environment: prod

server:

enable-self-preservation: false

eviction-interval-timer-in-ms: 30000

---

spring:

profiles: jm-citymap-common-prod01

eureka:

instance:

hostname: jm-citymap-common-prod01

instance-id: ${spring.cloud.client.ipAddress}:${server.port}

client:

register-with-eureka: true

fetch-registry: true

serviceUrl:

defaultZone: http://admin:1q2w3e4r5t6y7U@jm-citymap-common-prod02:8810/eureka/

原因分析:

defaultZone 配置

从配置文件看并没有出现localhost ,那从哪来的。查询eureka的服务注册发现相关源码剖析 EurekaClientConfigBean 中

public EurekaClientConfigBean() {

this.serviceUrl.put("defaultZone", "http://localhost:8761/eureka/");

//...

}

如果defaultZone没配置,默认就是http://localhost:8761/eureka/,而eureka server确实是配置了defaultZone。那会不会是配置的defaultZone 没生效。

Profiles 激活

从配置文件发现defaultZone配置是配置到了名为jm-citymap-common-prod01 的spring profiles 中。如果需要defaultZone 生效,必须激活名为jm-citymap-common-prod01 的spring profiles。 查看配置和启动命令。都没有激活jm-citymap-common-prod01。

✌解决方案:

在启动命令上加-Dspring.profiles.active=jm-citymap-common-prod01,激活jm-citymap-common-prod01.

nohup java -jar -Xms512m -Xmx512m -Dspring.profiles.active=jm-citymap-common-prod01 cloud-eureka.jar /opt/app/eureka/logs/ 2>&1 &

相关补充

Spring Profiles介绍

在 Spring Framework 中,Profile 是一种用于定义一组 Bean 定义和配置的机制,这些 Bean 定义和配置仅在特定的运行时环境或应用程序配置下生效。通过使用 Profile,你可以根据应用程序运行的环境,如开发环境、测试环境、生产环境等,来灵活地管理不同的配置。

在 Spring 中,可以通过以下方式使用 Profile:

在 XML 配置文件中使用 Profile

在注解配置中使用 Profile

@Configuration

public class AppConfig {

@Bean

@Profile("dev")

public DataSource dataSourceDev() {

// DataSource for development environment

}

@Bean

@Profile("prod")

public DataSource dataSourceProd() {

// DataSource for production environment

}

}

在属性文件中使用 Profile

# Common properties

---

spring:

profiles: dev

# Properties for development environment

---

spring:

profiles: prod

# Properties for production environment

profiles的激活方式

在Spring中,有多种方式可以激活profiles。以下是其中常用的几种方式:

命令行参数,在运行时使用-Dspring.profiles.active参数来指定激活的profile

java -jar your-application.jar -Dspring.profiles.active=dev

配置文件,在application.properties或者application.yml中直接配置

spring.profiles.active=dev

在代码中激活,在启动类或者配置类中通过Java代码来激活profiles

@SpringBootApplication

public class YourApplication {

public static void main(String[] args) {

SpringApplication application = new SpringApplication(YourApplication.class);

application.setAdditionalProfiles("dev");

application.run(args);

}

}

小结

通过这次问题的排查和解决,深刻认识到了Spring Profiles的重要性。在项目开发中,合理使用Profiles能够更好地适应不同的环境,提高系统的灵活性和可维护性。同时,在配置Eureka时,确保eureka defaultZone正确配置也是至关重要的。

精彩文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: