🏆项目场景:
最近在使用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/
🔎原因分析:
从配置文件看并没有出现localhost
,那从哪来的。查询eureka的服务注册发现相关源码剖析
eurekaclientconfigbean
中
public eurekaclientconfigbean() {
this.serviceurl.put("defaultzone", "http://localhost:8761/eureka/");
//...
}
如果defaultzone
没配置,默认就是http://localhost:8761/eureka/
,而eureka server确实是配置了defaultzone
。那会不会是配置的defaultzone
没生效。
从配置文件发现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
<beans>
<!-- common bean definitions -->
<beans profile="dev">
<!-- bean definitions for development environment -->
</beans>
<beans profile="prod">
<!-- bean definitions for production environment -->
</beans>
</beans>
- 在注解配置中使用 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正确配置也是至关重要的。
发表评论