我有一个使用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不在localhost上运行,它在我启动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“links”字段,但它并没有像我希望的那样工作。另外,如何将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
如果对您有用,那就是我在某种程度上为我的生产环境配置它(docker-compose file version 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'
来自docs,这是expose
所做的:
暴露端口而不将它们发布到主机 - 它们只能被链接服务访问。只能指定内部端口。
由于您拥有同一网络中的所有内容,因此容器可以看到彼此之间没有任何链接。
边注
请记住,使用此配置,端口9000将在主机上公开访问,并映射到用户注册容器的8080端口。
设置环境属性以覆盖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
这将覆盖打包的application.properties
中的属性。
注意:如评论中所述,您不需要撰写文件中的links
部分。我删除了就是这样。有关该信息,请参阅https://docs.docker.com/compose/networking/。
我有同样的问题,我尝试了一切,但它没有奏效。经过2周的试验和错误后,我试图从存储库中删除所有依赖项,然后我确保我在所有这些中都有相同的netflix客户端,服务器和Zuul依赖项。
然后我使用上面的解决方案,之后它对我有用。
还要注意,你需要使用docker compose启动服务,然后它才会起作用,否则如果你独立启动它们,那么它们将全部从它们的on容器开始,不会注册到服务注册表。希望这可以帮助