使用Spring Boot的Docker和Eureka无法注册客户端

ros*_*hal 4 java spring maven docker spring-boot

我有一个使用Spring Boot + Docker Compose + Eureka的非常简单的演示。

我的服务器在具有以下应用程序属性的端口8671上运行:

server:
  port: 8761
eureka:
  instance:
    prefer-ip-address: true
  client:
    registerWithEureka: false
    fetchRegistry: false
  server:
    waitTimeInMsWhenSyncEmpty: 0
Run Code Online (Sandbox Code Playgroud)

我的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
Run Code Online (Sandbox Code Playgroud)

当我在父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
Run Code Online (Sandbox Code Playgroud)

当我首先启动eureka服务器运行应用程序时,客户端通过

mvn spring-boot:run 
Run Code Online (Sandbox Code Playgroud)

服务器成功注册了我的客户端(我称其为用户注册)。

当我通过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)
Run Code Online (Sandbox Code Playgroud)

我的第一个假设是,在等待服务器启动时,运行docker-compose进入了竞争状态,但是我的eureka客户端似乎心跳不断,试图调用配置了该服务器的服务器。这意味着它只是无法找到我注册的Eureka服务器(并且正在运行,我可以在localhost:8671上导航到它)。

我在这里想念什么?使用本地自带的tomcat容器启动spring-boot,一切都可以在本地正常运行。一旦我开始使用docker-compose进行操作,它就不会工作。

编辑

我相信,我意识到了自己的问题。所以docker不在本地主机上运行,​​而是在我启动docker时分配的公共IP上运行。导航到该ip +端口显示我的服务正在为Eureka Server运行。客户端仍然没有注册。

因此,我将我的eureka客户端的application.yml文件更改为:

serviceUrl:
  defaultZone: http://192.168.59.103:8761/eureka/
Run Code Online (Sandbox Code Playgroud)

该IP是我的docker守护程序运行的IP。现在,当我执行docker-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
Run Code Online (Sandbox Code Playgroud)

M. *_*num 5

设置环境属性以覆盖,eureka.client.serviceUrl.defaultZone以匹配docker 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
Run Code Online (Sandbox Code Playgroud)

这将覆盖packaged中的属性application.properties

注意:注释中所述,您不需要links撰写文件中的该部分。我删除就是这样。有关此信息,请参阅https://docs.docker.com/compose/networking/


Tan*_*gar 5

更新:

看起来对于较新版本的 spring-boot (就我而言2.4.5),此解决方案不起作用。该EUREKA_CLIENT_SERVICEURL_DEFAULTZONE属性不会自动拾取。驼峰式封装存在一个永久性问题,会导致不一致。EUREKA_CLIENT_SERVICEURL_DEFAULTZONE不转换为eureka.client.serviceUrl.defaultZone. 它被转换为eureka.client.serviceurl.defaultzone. 请查看spring-cloud-netflix 的 Github Issue了解更多详细信息。他们现在无法更改参数,因为这将破坏向后兼容性。这是最终对我有用的代码

   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"}}}}'
Run Code Online (Sandbox Code Playgroud)

为了仅通过环境变量设置此属性,您必须使用 user SPRING_APPLICATION_JSON。它很丑,但很有效。


Xtr*_*ica 3

如果对您有用,这就是我在生产环境中配置它的方式(docker-compose 文件版本 2):

\n\n
version: \'2\'\nservices:\n  eureka-server:\n    image: rosenthal/eureka-server\n    expose:\n    - "8761"\n  user-registration:\n    image: rosenthal/user-registration\n    container_name: user-registration\n    ports:\n    - "9000:8080"\n    environment:\n      server.port: 8080\n      eureka.client.enabled: \'true\'\n      eureka.host: eureka-server\n      eureka.instance.preferIpAddress: \'true\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

文档来看,这就是expose

\n\n
\n

公开端口而不将它们发布到主机 - 它们\xe2\x80\x99只能由链接服务访问。只能指定内部端口。

\n
\n\n

由于所有内容都位于同一网络中,因此容器可以相互查看,而它们之间没有链接。

\n\n

边注

\n\n

请记住,通过此配置,端口 9000 将在主机上可公开访问,并映射到用户注册容器的 8080 端口。

\n