首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在重新启动客户端之前,Spring服务器无法与docker-compose连接。

在重新启动客户端之前,Spring服务器无法与docker-compose连接。
EN

Stack Overflow用户
提问于 2019-08-31 16:05:55
回答 4查看 4.4K关注 0票数 11

我有一个‘发现第一’设置与尤里卡,康菲服务器,和我的客户。

问题是这3种服务是按顺序启动的,但是客户端服务器似乎注册得太早,永远找不到配置服务器。我尝试过一个第三方库,它允许等待配置服务器:8888可用,但这似乎也不总是有效的。这和种族状况很相似。

解决办法是,如果在所有操作结束后我docker restart客户机服务器,它会注册并找到配置服务器。

第一次运行docker-compose

代码语言:javascript
复制
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客户端时:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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:

代码语言:javascript
复制
server:
  port: 8888

eureka:
  client:
    serviceUrl:
      defaultZone: ${EUREKA_SERVER:http://localhost:8761/eureka}

spring:
  application:
    name: config-server

下面是客户机服务器bootstrap.yml:

代码语言:javascript
复制
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秒),而且它似乎是一致工作的。

这是一个可以接受的解决办法吗?感觉有点像黑客。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-09-09 13:01:12

作为一个纯粹主义者,你的问题的答案是NO,这不是一个可接受的解决方案,因为正如它所说的这里,Docker出于某种原因将healthcheck从v3上删除了:

Docker已经有意识地决定不支持等待容器处于“就绪”状态的特性。他们认为,依赖于其他系统的应用程序应该具有抗故障能力。

在同一链接中,说明了为什么:

等待数据库(例如)就绪的问题实际上只是分布式系统这个大得多的问题的一个子集。在生产中,您的数据库可能在任何时候变得不可用或移动主机。您的应用程序需要对这些类型的故障具有弹性。 若要处理此问题,应用程序应尝试在失败后重新建立到数据库的连接。如果应用程序重新尝试连接,它最终应该能够连接到数据库。

基本上,有三种选择:

  1. healhcheck一起使用v2.1。参见这里示例
  2. 使用v3和像等-它-它码头化这样的工具作为@ortomala-lokni已经解释得很清楚了。
  3. 使您的应用程序能够抵御配置服务器故障和能够在启动时重新尝试连接的配置客户端。

建议的和可接受的解决方案是3)。您可以使用弹簧重试,因为这里提到了这里。在bootstrap.yml配置下面可以找到:

代码语言:javascript
复制
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,则类似):

代码语言:javascript
复制
<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
</dependency>

您可以找到一个非常好的配置(和解释) 这里,同时考虑到在Eureka服务器注册过程中的弹性。

当拥有微服务环境时,当配置服务、发现服务等平台服务在短时间内不可用时,我们必须考虑环境的弹性。

但我根本不是一个纯粹主义者,我也不会删除一些人们正在使用的功能(这是一个自由的问题)。因此,另一种解决办法是:

如果它对你有用,那就去吧

因为我真的不明白为什么Docker从v3中抑制了奇妙的v3命令。

票数 11
EN

Stack Overflow用户

发布于 2019-09-01 07:28:47

最好的解决方案可能是,正如卡洛斯·卡维罗所说,使您的应用程序具有抗配置服务器故障的能力。但是,您也可以通过使用来自wait-for埃菲奥德脚本来解决这个问题。

将脚本复制到容器中,并在docker-compose.yml中使用:

代码语言:javascript
复制
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_OPTIONS

CONFIGSERVER_SERVICE_NAMECONFIGSERVER_PORT的环境变量可以在Docker编写环境文件中定义。

如果需要等待多个服务,可以合并此拉请求并在命令行参数中列出所有需要的服务,如:

代码语言:javascript
复制
command: wait-for $SERVICE1_NAME $SERVICE1_PORT $SERVICE2_NAME $SERVICE2_PORT -- java $JVM_OPTIONS -jar client.war $SPRING_OPTIONS
票数 3
EN

Stack Overflow用户

发布于 2019-09-04 16:33:23

在使用docker-组合时,服务依赖总是很棘手的。

您的解决方案是可以接受的,因为“没有其他方法”。为了避免第三部分库,我在相同的场景中这样做:

在Dockerfile中,我添加了netcat-openbsd,一个名为entrypoint的bash文件和应用程序jar,然后运行entrypoint.sh。

代码语言:javascript
复制
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

入口点文件有以下指令:

代码语言:javascript
复制
#!/bin/sh

while ! nc -z config 8888 ; do
    echo "Waiting for upcoming Config Server"
    sleep 2
done

java -jar /opt/lib/app.jar

它将延迟应用程序的启动,直到您的配置服务器启动,而没有特定的间隔。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57739617

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档