我有一个‘发现第一’设置与尤里卡,康菲服务器,和我的客户。
问题是这3种服务是按顺序启动的,但是客户端服务器似乎注册得太早,永远找不到配置服务器。我尝试过一个第三方库,它允许等待配置服务器:8888可用,但这似乎也不总是有效的。这和种族状况很相似。
解决办法是,如果在所有操作结束后我docker restart客户机服务器,它会注册并找到配置服务器。
第一次运行docker-compose
Fetching config from server at : http://localhost:8888
Connect Timeout Exception on Url - http://localhost:8888. Will be trying the next url if available当我docker restart客户端时:
Fetching config from server at : http://a80b001d04a7:8888/
Located environment: name=client-server, profiles=[default], label=null, version=053c8e1b14dc0281d5af0349c9b2cf012c1a346f, state=null不确定我的JAVA_OPTS属性是否在我的docker-come.yml中设置得不够快,或者存在某种网络竞争条件,或者什么。我在这件事上来来回回已经太久了。
我的配置如下:
这是我的船坞-复合。Here:
version: '3'
services:
eureka:
image: eureka-server:latest
environment:
- "JAVA_OPTS=-DEUREKA_SERVER=http://eureka:8761/eureka"
ports:
- 8761:8761
config:
image: config-server:latest
environment:
- "JAVA_OPTS=-DEUREKA_SERVER=http://eureka:8761/eureka"
depends_on:
- eureka
ports:
- 8888:8888
client:
image: client-server:latest
environment:
JAVA_OPTS: -DEUREKA_SERVER=http://eureka:8761/eureka
depends_on:
- config
ports:
- 9000:9000下面是eureka服务器application.yml:
server:
port: 8761
spring:
application:
name: eureka-server
eureka:
client:
registerWithEureka: false
fetchRegistry: false
service-url:
defaultZone: ${EUREKA_SERVER:http://localhost:8761/eureka}下面是配置服务器bootstrap.yml:
server:
port: 8888
eureka:
client:
serviceUrl:
defaultZone: ${EUREKA_SERVER:http://localhost:8761/eureka}
spring:
application:
name: config-server下面是客户机服务器bootstrap.yml:
spring:
application:
name: client-server
cloud:
config:
discovery:
enabled: true
serviceId: config-server
fast-fail: true
retry:
max-attempts: 10000
max-interval: 1000
eureka:
instance:
hostname: client-server
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: ${EUREKA_SERVER:http://localhost:8761/eureka}编辑:
使用停靠-撰写等待库(https://github.com/ufoscout/docker-compose-wait),我可以让客户端服务器等待eureka和config可用,然后等待90秒(Eureka文档表明注册可能需要90秒),而且它似乎是一致工作的。
这是一个可以接受的解决办法吗?感觉有点像黑客。
发布于 2019-09-09 13:01:12
作为一个纯粹主义者,你的问题的答案是NO,这不是一个可接受的解决方案,因为正如它所说的这里,Docker出于某种原因将healthcheck从v3上删除了:
Docker已经有意识地决定不支持等待容器处于“就绪”状态的特性。他们认为,依赖于其他系统的应用程序应该具有抗故障能力。
在同一链接中,说明了为什么:
等待数据库(例如)就绪的问题实际上只是分布式系统这个大得多的问题的一个子集。在生产中,您的数据库可能在任何时候变得不可用或移动主机。您的应用程序需要对这些类型的故障具有弹性。 若要处理此问题,应用程序应尝试在失败后重新建立到数据库的连接。如果应用程序重新尝试连接,它最终应该能够连接到数据库。
基本上,有三种选择:
healhcheck一起使用v2.1。参见这里示例建议的和可接受的解决方案是3)。您可以使用弹簧重试,因为这里提到了这里。在bootstrap.yml配置下面可以找到:
spring:
application:
name: config-client
profiles:
active: dev
cloud:
config:
discovery:
enabled: true
service-id: config-server
fail-fast: true
retry:
initial-interval: 1500
multiplier: 1.5
max-attempts: 10000
max-interval: 1000
eureka:
instance:
hostname: config-client
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: ${EUREKA_SERVER:http://localhost:8761/eureka}顺便说一下,我在您的spring配置中发现了一个错误。这是fail-fast而不是fast-fail。
请记住包括以下依赖项(如果使用gradle,则类似):
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>您可以找到一个非常好的配置(和解释) 这里,同时考虑到在Eureka服务器注册过程中的弹性。
当拥有微服务环境时,当配置服务、发现服务等平台服务在短时间内不可用时,我们必须考虑环境的弹性。
但我根本不是一个纯粹主义者,我也不会删除一些人们正在使用的功能(这是一个自由的问题)。因此,另一种解决办法是:
如果它对你有用,那就去吧
因为我真的不明白为什么Docker从v3中抑制了奇妙的v3命令。
发布于 2019-09-01 07:28:47
最好的解决方案可能是,正如卡洛斯·卡维罗所说,使您的应用程序具有抗配置服务器故障的能力。但是,您也可以通过使用来自wait-for的埃菲奥德脚本来解决这个问题。
将脚本复制到容器中,并在docker-compose.yml中使用:
client:
image: client-server:latest
environment:
JAVA_OPTS: -DEUREKA_SERVER=http://eureka:8761/eureka
depends_on:
- config
ports:
- 9000:9000
command: wait-for $CONFIGSERVER_SERVICE_NAME:$CONFIGSERVER_PORT -- java $JVM_OPTIONS -jar client.war $SPRING_OPTIONSCONFIGSERVER_SERVICE_NAME和CONFIGSERVER_PORT的环境变量可以在Docker编写环境文件中定义。
如果需要等待多个服务,可以合并此拉请求并在命令行参数中列出所有需要的服务,如:
command: wait-for $SERVICE1_NAME $SERVICE1_PORT $SERVICE2_NAME $SERVICE2_PORT -- java $JVM_OPTIONS -jar client.war $SPRING_OPTIONS发布于 2019-09-04 16:33:23
在使用docker-组合时,服务依赖总是很棘手的。
您的解决方案是可以接受的,因为“没有其他方法”。为了避免第三部分库,我在相同的场景中这样做:
在Dockerfile中,我添加了netcat-openbsd,一个名为entrypoint的bash文件和应用程序jar,然后运行entrypoint.sh。
FROM openjdk:8-jdk-alpine
RUN apk --no-cache add netcat-openbsd
COPY entrypoint.sh /opt/bin/
COPY app.jar /opt/lib/
RUN chmod 755 /opt/esusab-bi/bin/app/entrypoint.sh入口点文件有以下指令:
#!/bin/sh
while ! nc -z config 8888 ; do
echo "Waiting for upcoming Config Server"
sleep 2
done
java -jar /opt/lib/app.jar它将延迟应用程序的启动,直到您的配置服务器启动,而没有特定的间隔。
https://stackoverflow.com/questions/57739617
复制相似问题