alibaba / spring-cloud-alibaba

Spring Cloud Alibaba provides a one-stop solution for application development for the distributed solutions of Alibaba middleware.
https://sca.aliyun.com
Apache License 2.0
27.42k stars 8.17k forks source link

Nacos connection retry question #3611

Closed cxhello closed 3 months ago

cxhello commented 4 months ago

Which Component

Spring Boot 2.3.2.RELEASE Spring Cloud Hoxton.SR9 Spring Cloud Alibaba 2.2.6.RELEASE Nacos Client 2.1.2 Nacos Server 2.2.3

Is your feature request related to a problem? Please describe.

Our applications are deployed using docker compose (including nacos). The physical machines deployed to the customer company will occasionally be restarted. Currently, we do not do the startup sequence of the containers. Sometimes the Spring Boot application will start before the Nacos Server, and I learned that the Nacos Client will keep retrying. The current problem is that after Nacos Server is started, the Spring Boot application still cannot connect to Nacos Server, but I use the docker command to manually restart the Spring Boot application and it returns to normal (docker restart nacos-client). So I'm confused and want to ask for advice.

我们的应用是采用 docker compose 方式部署的(包括nacos),部署到客户公司的物理机器偶尔会重启,当前我们没有做容器的启动顺序。有时 Spring Boot 应用会优先于 Nacos Server 启动,我了解到 Nacos Client 会一直重试。目前的问题是当 Nacos Server 启动后,Spring Boot 应用还是无法连接 Nacos Server,但我使用 docker 命令手动重启 Spring Boot 应用就恢复正常(docker restart nacos-client)。所以我比较困惑,想请教一下。

Describe the solution you'd like

It is expected that the Spring Boot application will retry successfully connecting to Nacos Server or allow the number of retries to be set, and the process will be stopped when the number of retries is reached.

Describe alternatives you've considered

Set the container dependency order, wait for Nacos Server to start, and then start the nacos-client application. I haven't tried this method yet

Additional context

The following are the error messages that have occurred

Caused by: com.alibaba.nacos.api.exception.NacosException: user not found!

Caused by: com.alibaba.nacos.api.exception.NacosException: Client not connected, current status:STARTING

image image

One of these two situations will always occur.

yuluo-yx commented 4 months ago

使用 docker-compose 重启的时候,如果不指定启动顺序,sb 应用在先于 nacos 启动的时候,就会去连接 nacos, 如果 nacos 在sb 应用重试之后还没有启动成功,就会启动失败。一般 docker 启动 nacos 初始化数据等等耗时会比较长

  1. 看下 sb 应用中有没有设置 spring.cloud.nacos.discovery.username/password 属性;
  2. nacos server 在 2.x 版本之后加入了用户鉴权,user not found 可能是用户配置不合适,可以参考下 nacos 鉴权部分看看;
  3. nacos 初始化资源没有完成。
    1. 可以把 nacos 和 其他应用依赖的组件放到一个 compose 文件中,应用分开,当依赖组件启动成功的时候再去启动应用。
    2. 添加 nacos 健康检查,确定启动顺序。
      healthcheck:
        test: [ "CMD", "curl", "-f", "http://localhost:8848/nacos/v1/console/health/readiness" ]
        interval: 10s
        timeout: 20s
        retries: 10
cxhello commented 4 months ago

使用 docker-compose 重启的时候,如果不指定启动顺序,sb 应用在先于 nacos 启动的时候,就会去连接 nacos, 如果 nacos 在sb 应用重试之后还没有启动成功,就会启动失败。一般 docker 启动 nacos 初始化数据等等耗时会比较长

  1. 看下 sb 应用中有没有设置 spring.cloud.nacos.discovery.username/password 属性;
  2. nacos server 在 2.x 版本之后加入了用户鉴权,user not found 可能是用户配置不合适,可以参考下 nacos 鉴权部分看看;
  3. nacos 初始化资源没有完成。

    1. 可以把 nacos 和 其他应用依赖的组件放到一个 compose 文件中,应用分开,当依赖组件启动成功的时候再去启动应用。
    2. 添加 nacos 健康检查,确定启动顺序。
      healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost:8848/nacos/v1/console/health/readiness" ]
      interval: 10s
      timeout: 20s
      retries: 10
  1. 目前设置了spring.cloud.nacos.username&password属性,没有在spring.cloud.nacos.discovery.username/password这一层设置;
  2. 手动再重启应用就没问题了,但是我看nacos文档说client会一直重试,因为应用的进程还一直在并没有死掉,所以来咨询下;
  3. 这种方案考虑过,但是我们应用比较多。之前已经将docker-compose文件拆分成了多个,所以没法使用depends_on;
yuluo-yx commented 4 months ago

使用 docker-compose 重启的时候,如果不指定启动顺序,sb 应用在先于 nacos 启动的时候,就会去连接 nacos, 如果 nacos 在sb 应用重试之后还没有启动成功,就会启动失败。一般 docker 启动 nacos 初始化数据等等耗时会比较长

  1. 看下 sb 应用中有没有设置 spring.cloud.nacos.discovery.username/password 属性;
  2. nacos server 在 2.x 版本之后加入了用户鉴权,user not found 可能是用户配置不合适,可以参考下 nacos 鉴权部分看看;
  3. nacos 初始化资源没有完成。

    1. 可以把 nacos 和 其他应用依赖的组件放到一个 compose 文件中,应用分开,当依赖组件启动成功的时候再去启动应用。
    2. 添加 nacos 健康检查,确定启动顺序。
      healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost:8848/nacos/v1/console/health/readiness" ]
      interval: 10s
      timeout: 20s
      retries: 10
  1. 目前设置了spring.cloud.nacos.username&password属性,没有在spring.cloud.nacos.discovery.username/password这一层设置;
  2. 手动再重启应用就没问题了,但是我看nacos文档说client会一直重试,因为应用的进程还一直在并没有死掉,所以来咨询下;
  3. 这种方案考虑过,但是我们应用比较多。之前已经将docker-compose文件拆分成了多个,所以没法使用depends_on;

大致明白了你的意思,就是按照文档描述,sb 应用会一直重试去尝试连接 nacos,而不是像是现在这样终止应用?😯

cxhello commented 4 months ago

使用 docker-compose 重启的时候,如果不指定启动顺序,sb 应用在先于 nacos 启动的时候,就会去连接 nacos, 如果 nacos 在sb 应用重试之后还没有启动成功,就会启动失败。一般 docker 启动 nacos 初始化数据等等耗时会比较长

  1. 看下 sb 应用中有没有设置 spring.cloud.nacos.discovery.username/password 属性;
  2. nacos server 在 2.x 版本之后加入了用户鉴权,user not found 可能是用户配置不合适,可以参考下 nacos 鉴权部分看看;
  3. nacos 初始化资源没有完成。

    1. 可以把 nacos 和 其他应用依赖的组件放到一个 compose 文件中,应用分开,当依赖组件启动成功的时候再去启动应用。
    2. 添加 nacos 健康检查,确定启动顺序。
      healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost:8848/nacos/v1/console/health/readiness" ]
      interval: 10s
      timeout: 20s
      retries: 10
  1. 目前设置了spring.cloud.nacos.username&password属性,没有在spring.cloud.nacos.discovery.username/password这一层设置;
  2. 手动再重启应用就没问题了,但是我看nacos文档说client会一直重试,因为应用的进程还一直在并没有死掉,所以来咨询下;
  3. 这种方案考虑过,但是我们应用比较多。之前已经将docker-compose文件拆分成了多个,所以没法使用depends_on;

大致明白了你的意思,就是按照文档描述,sb 应用会一直重试去尝试连接 nacos,而不是像是现在这样终止应用?😯

现在也不会终止进程,但是应用的状态不是正常的,会提示截图中的错误信息,接口也无法正常调用。

yuluo-yx commented 4 months ago

现在也不会终止进程,但是应用的状态不是正常的,会提示截图中的错误信息,接口也无法正常调用。

get.

cxhello commented 4 months ago

get.

目前我能想到的一个方案是从部署角度解决的,在 docker compose 文件中 增加

entrypoint: /bin/sh -c "until curl -f http://nacos:8848/nacos/v1/console/health/readiness; do echo 'Waiting for Nacos...'; sleep 5; done && exec java -Dfile.encoding=UTF-8 -jar app.jar"

yuluo-yx commented 4 months ago

get.

目前我能想到的一个方案是从部署角度解决的,在 docker compose 文件中 增加

entrypoint: /bin/sh -c "until curl -f http://nacos:8848/nacos/v1/console/health/readiness; do echo 'Waiting for Nacos...'; sleep 5; done && exec java -Dfile.encoding=UTF-8 -jar app.jar"

可以提供一个简单复现的例子出来吗?可以是 github 仓库连接

cxhello commented 4 months ago

好的,明天我发出来。

cxhello commented 4 months ago

@yuluo-yx

github仓库链接:https://github.com/cxhello/spring-cloud-nacos.git

image

这个是我刚刚使用这个示例的的日志,进程还在,但是接口无法正常调用。

yuluo-yx commented 3 months ago

@cxhello 你好,这几天有点事情,耽搁了,你可以在配置文件中尝试加入以下配置

spring:
  cloud:
    nacos:
      discovery:
        fail-fast=false

Feb-03-2024 10-45-58

sca 加入了注册中心的快速失败机制,具体可见

  1. https://github.com/alibaba/spring-cloud-alibaba/pull/2104
  2. https://github.com/alibaba/spring-cloud-alibaba/blob/2d107bf057cefc2705d426b05f68786bb74477ed/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java#L81
cxhello commented 3 months ago

@yuluo-yx 我刚刚尝试了设置为false也是一种解决方案。另外我看到了一个issue

https://github.com/alibaba/spring-cloud-alibaba/issues/2288

我想知道是不是这个issue中提到的bug导致的主进程未停止,是假死状态。

yuluo-yx commented 3 months ago

@yuluo-yx 我刚刚尝试了设置为false也是一种解决方案。另外我看到了一个issue

2288

我想知道是不是这个issue中提到的bug导致的主进程未停止,是假死状态。

yep, 确实有此问题,使用的 sca 版本是 2.2.6.RELEASE,如 issue 中描述的那样,你可以切换到 2.2.7 版本看下问题是否解决了。🤔🤔

cxhello commented 3 months ago

@yuluo-yx 感谢。