nacos icon indicating copy to clipboard operation
nacos copied to clipboard

nacos2.2.4client-服务端2.2.3相关问题

Open xorange1997 opened this issue 4 months ago • 16 comments

作者们,你们好,目前碰到一个奇怪的问题,想要咨询一下,目前我们系统启动时通过ConfigService中getConfig去获取配置,但是无法获取到,但是只要我在这一行debug之后,就能正常读取到配置,请问一下这是什么原因导致的?万分感谢 image

xorange1997 avatar Mar 26 '24 02:03 xorange1997

感觉需要更多详细信息才能确认问题。我感觉应该不是nacos的问题,应该是你使用出问题了,debug应该不影响配置的获取。

stone-98 avatar Mar 26 '24 06:03 stone-98

是否有异常信息呢?

stone-98 avatar Mar 26 '24 06:03 stone-98

感觉需要更多详细信息才能确认问题。我感觉应该不是nacos的问题,应该是你使用出问题了,debug应该不影响配置的获取。

请问一下 在哪里看这个日志比较全面?目前我看到有异常的日志就只有这个,但是我8848、9848、9849端口使用telnet查看是通的 image

xorange1997 avatar Mar 26 '24 07:03 xorange1997

感觉需要更多详细信息才能确认问题。我感觉应该不是nacos的问题,应该是你使用出问题了,debug应该不影响配置的获取。

并且我在idea中远程debug此服务器上的代码之后,就能正常获取到了?所以感觉很奇怪。

xorange1997 avatar Mar 26 '24 07:03 xorange1997

你这个是启动的时候去获取config嘛?可能是因为sdk还没成功连接到server,所以显示连接状态是starting中,从而获取失败,你debug能获取到,可能是在你debug的过程中sdk连接上了server。

stone-98 avatar Mar 26 '24 07:03 stone-98

你这个是启动的时候去获取config嘛?可能是因为sdk还没成功连接到server,所以显示连接状态是starting中,从而获取失败,你debug能获取到,可能是在你debug的过程中sdk连接上了server。

是的 我是启动的时候去获取config的,并且不是springboot框架,目前来看就是这样的原因,加大nacos.remote.client.grpc.retry.times重试次数后能够获取到配置了,但是原因还未找到,请问初始化客户端是异步的吗?调用的时候没初始化?

xorange1997 avatar Mar 26 '24 09:03 xorange1997

看了下代码,原因应该是: https://github.com/alibaba/nacos/blob/3a1f0c297e37608035514a98ebc51133daad7863/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java#L1144-L1156 通过ensureRpcClient方法去初始化RpcClient,但是这个初始化过程是异步的,拿到这个RpcClient就直接去进行配置查询,由于RpcClient与连接还没创建成功,所以直接抛出异常"Client not connected, current status: STARTING"。 其实按道理 https://github.com/alibaba/nacos/blob/3a1f0c297e37608035514a98ebc51133daad7863/common/src/main/java/com/alibaba/nacos/common/remote/client/RpcClient.java#L632-L700 对于状态的判断应该要是一个同步操作,如果RpcClient在timeout时间都没成功建立连接才抛出异常,而不是直接判断status != running就抛出异常。

stone-98 avatar Mar 26 '24 09:03 stone-98

看了下代码,原因应该是:

https://github.com/alibaba/nacos/blob/3a1f0c297e37608035514a98ebc51133daad7863/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java#L1144-L1156

通过ensureRpcClient方法去初始化RpcClient,但是这个初始化过程是异步的,拿到这个RpcClient就直接去进行配置查询,由于RpcClient与连接还没创建成功,所以直接抛出异常"Client not connected, current status: STARTING"。 其实按道理 https://github.com/alibaba/nacos/blob/3a1f0c297e37608035514a98ebc51133daad7863/common/src/main/java/com/alibaba/nacos/common/remote/client/RpcClient.java#L632-L700

对于状态的判断应该要是一个同步操作,如果RpcClient在timeout时间都没成功建立连接才抛出异常,而不是直接判断status != running就抛出异常。

那请问一下 这种比较好的解决办法是什么勒?感觉加大重试次数 不是一个很好的办法勒?这种算bug吗?

xorange1997 avatar Mar 26 '24 09:03 xorange1997

我个人觉得算bug把,看看其他大佬有没有什么更好解决方法。

stone-98 avatar Mar 26 '24 09:03 stone-98

主要得看一下深层原因,为什么连接的会慢吧。

KomachiSion avatar Mar 28 '24 06:03 KomachiSion

对于状态的判断应该要是一个同步操作,如果RpcClient在timeout时间都没成功建立连接才抛出异常,而不是直接判断status != running就抛出异常。

这个不行的, 那就变成应用强制依赖nacos稳定性和网络稳定性, 这样就完全失去了可用性和容灾能力。

实际上nacos-client在连不上服务端的时候,是可以通过snapshot返回配置的, 不会因为nacos挂了阻塞业务启动。实在不行还有failover可以不阻塞业务启动。

但是如果client连不上就抛异常,那意味着用户如果不自己捕获异常处理,然后走下去,就必然阻塞业务。

KomachiSion avatar Apr 03 '24 08:04 KomachiSion

对于状态的判断应该要是一个同步操作,如果RpcClient在timeout时间都没成功建立连接才抛出异常,而不是直接判断status != running就抛出异常。

这个不行的, 那就变成应用强制依赖nacos稳定性和网络稳定性, 这样就完全失去了可用性和容灾能力。

实际上nacos-client在连不上服务端的时候,是可以通过snapshot返回配置的, 不会因为nacos挂了阻塞业务启动。实在不行还有failover可以不阻塞业务启动。

但是如果client连不上就抛异常,那意味着用户如果不自己捕获异常处理,然后走下去,就必然阻塞业务。

get到了,那如果服务端连接的处理过慢,那感觉没有太好的解决方法了。

stone-98 avatar Apr 07 '24 09:04 stone-98

应该是可以优化的, 我记得java client就优化过, 首次连接未成功前,会阻塞一次,如果首次连接超过重试次数未成功,结束阻塞,让应用逻辑走下去。代价就是如果连接不畅的话, 可能启动会慢几秒。

KomachiSion avatar Apr 22 '24 02:04 KomachiSion

应该是可以优化的, 我记得java client就优化过, 首次连接未成功前,会阻塞一次,如果首次连接超过重试次数未成功,结束阻塞,让应用逻辑走下去。代价就是如果连接不畅的话, 可能启动会慢几秒。

这样感觉ok诶,那我晚点把它处理一下。

stone-98 avatar Apr 22 '24 06:04 stone-98

应该是可以优化的, 我记得java client就优化过, 首次连接未成功前,会阻塞一次,如果首次连接超过重试次数未成功,结束阻塞,让应用逻辑走下去。代价就是如果连接不畅的话, 可能启动会慢几秒。

这样感觉ok诶,那我晚点把它处理一下。

我遇到了同样的问题,服务起不来,nacos-client版本降到1.4.7后正常启动,但nacos控制台无法看到实例。nacos版本2.3.0,请问有解决办法吗?

Fahoud avatar Apr 25 '24 07:04 Fahoud

应该是可以优化的, 我记得java client就优化过, 首次连接未成功前,会阻塞一次,如果首次连接超过重试次数未成功,结束阻塞,让应用逻辑走下去。代价就是如果连接不畅的话, 可能启动会慢几秒。

现在的逻辑就是这样的,当RpcClient发起调用时,如果状态不是Running,只要没有超过超时时间和重试次数,则会进行重试。 所以这里这里其实这里可以通过合适的超时时间和重试次数进行避免该问题。

只是感觉这个重试间隔有点短了,最多隔100ms重试一次,现在的重试机制基于超时时间和重试次数共同控制,只要有一个不满足则请求失败,现在默认超时时间3s,默认重试次数3次,如果连接接口时间大于300ms就连接不上了,感觉重试时间设置个1000ms比较合适,如果觉得这个可行的话我可以提交下PR。

stone-98 avatar Apr 25 '24 14:04 stone-98