![](/img/trans.png)
[英]How to register eureka-clients with eureka-server on different hosts. Spring-boot
[英]Docker and Eureka with Spring Boot failing to register clients
我有一个非常简单的使用 Spring Boot + Docker Compose + Eureka 的演示。
我的服务器在端口 8671 上运行,具有以下应用程序属性:
server:
port: 8761
eureka:
instance:
prefer-ip-address: true
client:
registerWithEureka: false
fetchRegistry: false
server:
waitTimeInMsWhenSyncEmpty: 0
我的 Eureka 客户端在端口 9000 上运行,具有以下应用程序属性:
server:
port: 9000
spring:
application:
name: user-registration
eureka:
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
当我在父 maven 项目中启动我的 docker.compose 文件时,这是我的 docker-compose 文件的内容:
eureka-server:
image: rosenthal/eureka-server
ports:
- "8761:8761"
user-registration:
image: rosenthal/user-registration
ports:
- "9000:9000"
links:
- eureka-server
当我首先启动 eureka 服务器运行我的应用程序时,然后通过客户端
mvn spring-boot:run
服务器成功注册了我的客户端(我称之为用户注册)。
当我通过 docker-compose 运行我的应用程序时,客户端无法注册以下输出:
DiscoveryClient_USER-REGISTRATION/0fd640cbc3ba:user-registration:9000:
registering service...
user-registration_1 | 2017-06-21 04:36:05.120 ERROR 1 --- [nfoReplicator-0]
c.n.d.s.t.d.RedirectingEurekaHttpClient : Request execution error
user-registration_1 |
user-registration_1 | com.sun.jersey.api.client.ClientHandlerException:
java.net.ConnectException: Connection refused (Connection refused)
我的第一个假设是运行 docker-compose 在等待服务器启动时遇到了竞争条件,但我的 eureka 客户端似乎有一个心跳试图调用它配置的服务器。 这意味着它无法找到我注册的 Eureka 服务器(并且正在运行,我可以在 localhost:8671 上导航到它)。
我在这里错过了什么? 一切运行良好,在本地运行 spring-boot 启动它自己的嵌入式 tomcat 容器。 一旦我开始用 docker-compose 做这件事,它就不想工作了。
我意识到我的问题,我相信。 因此,docker 不在本地主机上运行,而是在我启动 docker 时分配的公共 IP 上运行。 导航到此 ip + 端口会显示我的服务正在为 Eureka Server 运行。 客户端仍然没有注册。
所以,我对 eureka 客户端的 application.yml 文件进行了更改:
serviceUrl:
defaultZone: http://192.168.59.103:8761/eureka/
该 IP 是我的 docker 守护程序正在运行的 IP。 现在,当我执行 docker-compose 时,它错过了第一次注册,但是第二次心跳接上了我的客户端。
如何确保客户端等待服务器完全启动? 我在我的 docket compose 文件中使用了正确的 docker“链接”字段,但它没有像我希望的那样工作。 此外,如何将 defaultZone 文件视为我的 DOCKER_HOST IP?
生成的 docker-compose 文件为我提供了一切工作:
eureka-server:
image: thorrism/eureka-server
ports:
- "8761:8761"
user-registration:
image: thorrism/user-registration
ports:
- "9000:9000"
links:
- eureka-server
environment:
EUREKA_CLIENT_SERVICEURL_DEFAULTZONE: http://eureka-server:8761/eureka
设置环境属性以覆盖eureka.client.serviceUrl.defaultZone
以匹配eureka.client.serviceUrl.defaultZone
compose 文件中的服务名称。
eureka-server:
image: rosenthal/eureka-server
ports:
- "8761:8761"
user-registration:
image: rosenthal/user-registration
ports:
- "9000:9000"
environment:
- EUREKA_CLIENT_SERVICEURL_DEFAULTZONE: http://eureka-server:8761/eureka
这将覆盖打包的application.properties
的属性。
注意:如评论中所述,您不需要撰写文件中的links
部分。 我删除是这样的。 有关这方面的信息,请参阅https://docs.docker.com/compose/networking/ 。
如果对您有用,这就是我为生产环境配置它的方式(docker-compose 文件版本 2):
version: '2'
services:
eureka-server:
image: rosenthal/eureka-server
expose:
- "8761"
user-registration:
image: rosenthal/user-registration
container_name: user-registration
ports:
- "9000:8080"
environment:
server.port: 8080
eureka.client.enabled: 'true'
eureka.host: eureka-server
eureka.instance.preferIpAddress: 'true'
从文档中, expose
是:
公开端口而不将它们发布到主机——它们只能被链接的服务访问。 只能指定内部端口。
由于您在同一个网络中拥有所有内容,因此容器可以相互看到,而它们之间没有链接。
边注
请记住,使用此配置端口 9000 将可在主机上公开访问,并映射到用户注册容器的 8080 端口。
更新:
看起来对于较新版本的 spring-boot(在我的情况下2.4.5
),此解决方案不起作用。 EUREKA_CLIENT_SERVICEURL_DEFAULTZONE
属性不会自动选取。 camelcasing 存在一个永久性问题,会造成不一致。 EUREKA_CLIENT_SERVICEURL_DEFAULTZONE
不会转换为eureka.client.serviceUrl.defaultZone
。 它被转换为eureka.client.serviceurl.defaultzone
。 有关更多详细信息,请查看spring-cloud-netflix 的这个Github 问题。 他们现在不能更改参数,因为这会破坏向后兼容性。 这是最终对我有用的代码
discovery:
container_name: discovery
build: .
ports:
- "8761:8761"
user-registration:
container_name: user-registration
build: .
ports:
- "8080:8080"
environment:
SPRING_APPLICATION_JSON: '{"eureka":{"client":{"serviceUrl":{"defaultZone":"http://discovery:8761/eureka"}}}}'
要仅通过环境变量设置此属性,您必须使用SPRING_APPLICATION_JSON
。 这是丑陋的,但它的工作原理。
我有同样的问题,我尝试了一切,但没有奏效。 经过 2 周的反复试验,然后我尝试从存储库中删除所有依赖项,然后确保我在所有这些中都具有相同的 netflix 客户端、服务器和 Zuul 依赖项。
然后我使用了上述解决方案,之后它对我有用。
还请注意,您需要使用 docker compose 启动服务,然后它才会工作,否则如果您独立启动它们,那么它们都将在它们的容器中启动,并且不会在服务注册表中注册。 希望这有帮助
作为@Tanbir Sagar 解决方案的替代方案,这对我有用:
discovery:
container_name: discovery
build: .
ports:
- "8761:8761"
user-registration:
container_name: user-registration
build: .
ports:
- "8080:8080"
environment:
eureka.client.serviceUrl.defaultZone: http://discovery:8761/eureka
使用 Spring Boot 2.5.6
和 Docker Compose 3
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.