-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
springCloudAlibaba+dubbo+nacos环境下,重启服务提供者或先启动服务消费者后启动服务提供者的情况下,消费者有时候会出现找不到服务的问题及解决方案(In the spring cloud Alibaba + Dubbo + Nacos environment, when the service provider is restarted or the service consumer is started first and then the service provider, sometimes the consumer can not find the service when calling) #1805
Comments
看来不少人碰到这个问题,感觉是不是解决方向上有问题,如果出现这种情况,重新从注册中心取一次数据更新会更合适。 |
官方说解决了,其实根本没解决,我也发现这个问题,而且确实是有概率的,并不是毕现。 |
可能是产生的原因很多~~,刚试出一次,然后怎么调都是这个提示,最后在nacos上把服务下线,再上线,就可以访问了。希望官方能不能有这个提示的时候从注册中心重新拉一下数据,明明服务是可用的。 |
这个问题再k8s环境是必现的,感谢大佬的方案,准备按方案b试一下 |
b方法 刚试了下 没有效果啊。 但是在nacos上把服务下线后,然后再上线 这样是有效果的 |
代码执行了没有?我测试提供者启动后下线再上线好像是可以的。不过我是直接把代码加到main里了,没像上面这么用。 |
我有一个问题,为什么在心跳处理时不把这些问题解决一下. 还有,在注册了 |
正因为有异步的存在,所以答主的第一个解决方案感觉不是很可行 |
在k8s环境,方案b没有效果,可以正常消费,但是依然会去尝试连接老的IP |
@mercyblitz 小马哥这个问题是不是后续版本都不打算解决了哇 |
k8s环境下,使用以下版本,只会打印一次错误日志,可以说已经解决了问题
关键日志如下
|
emmm...而且还出现同一个服务,一部分dubbo接口能用,一部分dubbo接口不能用的情况. |
已经困惑开发组人员很久的问题,当SpringCloud两个微服务相互成为提供者、消费者时,似乎无解!之前开发组把nacos://改成spring-cloud://连接前缀后得1、2天,之后该问题又再重现。希望早点有新版解决该问题。 |
亲,我这边建议您弃坑。 |
信仰要充值! 其实再提供者重启完成时,消费者是能接收到的,在消费者的控制台会有下面的内容输出: 最后一句提示: 只是不知道为啥消费者还是认不出提供者已经存活,调用时直接认为服务不存在: 开发还是要继续,项目还是要继续,所以也只能通过手动下线提供者再重新上线方式,让消费者重新和提供者握手! |
按照上面的例子我想本地模拟一下,但是好像不能复现 |
我说说一下开发组的环境: 服务: |
我又来刷屏了! 开发组确定了问题所在,之前项目用的版本是: 再升级到新版: |
k8s环境下,用的是文档推荐的最新毕业版本,nacos是1.3.2 Spring Cloud Version | Spring Cloud Alibaba Version | Spring Boot Version 2020-12-28 17:44:06.811 [dubbo-client-idleCheck-thread-1] [] ERROR org.apache.dubbo.remoting.exchange.support.header.ReconnectTimerTask - [DUBBO] Fail to connect to HeaderExchangeClient [channel=org.apache.dubbo.remoting.transport.netty4.NettyClient [/10.xx.xx.54:55378 -> /10.xx.xx.172:20880]], dubbo version: 2.7.8, current host: 10.xx.xx.54 能不能来个版本解决下呀。 还有一个问题,操作发版,导致服务启动完后,服务A不能调用服务B,一直在报错 |
我用的这个版本,依然存在消费者找不到提供者问题! |
@pangshuqiang |
@yuhuangbin @theonefx 这个问题官方有计划解决吗? |
We are dealing with this issue |
由于 spring cloud 对服务注册的概念和 dubbo 是不太一样的。
|
2.2.5.RELEASE问题依旧存在 |
我用spring cloud alibaba 2.2.5.RELEASE,也一直是这个问题 |
你可以看下2079,这已经成为一个官方暂时无法解决的BUG了 |
我升级到最新版本,但是问题还是存在,是还没有解决吗? |
抱歉,之前的修复确实有一些问题,导致解决的不够彻底。 |
抱歉,之前的修复确实有一些问题,导致解决的不够彻底。 |
抱歉,之前的修复确实有一些问题,导致解决的不够彻底。 |
2.2.6.RELEASE大概什么时候能发布 |
近期就会发布,原计划是这个月发布的,因为测试可能稍微有些delay |
感谢,辛苦了 |
spring cloud alibaba 2.2.6.RELEASE |
spring cloud alibaba 2.2.6.RELEASE |
你们是不是在调试时几个相互订阅服务同时启动? 根据我调试结果得出、几个服务在同时启动时、先启动好的服务注册入nacos之后、发生服务变更事件、nacos并不会通知正在注册中的服务、从而导致后注册上的服务没有获取到最新的订阅服务信息、如果每个服务顺序启动是不会有此问题的。 为了避免在注册中途有订阅服务注册上nacos却没有通知到本服务、故此我在服务启动之后会主动去发起一次订阅服务更新事件、经过测试之后已经解决此问题。 环境:
|
spring cloud alibaba 2.2.6.RELEASE |
重申一下这个问题,不要再掉坑里啦! 第一:不要用、不要用、不要用 spring-cloud-alibaba 自带的 Dubbo 版本 第二:一定要、一定要、一定要 Apache 管理的 Dubbo 版本,version >= 2.7.10 (2.7.9版本后基本解决找不到服务问题)
第三:把 Nacos 升级到 2.0 版本,不是必须的,但建议升级。 ### (题外话:spring-cloud-alibaba的seata一样,不要用自带的,单独引入seata的新包!!!) |
兄弟,方便贴一下你的版本依赖吗 |
我有一个服务提供程序,和一个服务消费程序 |
spring cloud :2020.0.5 也出现此类问题,同问 spring cloud alibaba :2021.1 新版本什么时候发布。几十个 项目刚升级到springboot 2.4.13,不想再降到 2.3.x 太麻烦了 |
666,使用这个方法解决问题,赞!!! |
这个还有种情况不行,当消费者、提供者同时启动,都处于注册过程中,消费者先启动成功,执行CustomDubboActiveProbeSubscriptionService,此时提供者未注册完成,所以获得改变0。之后提供者注册成功,但是消费者仍然订阅不到变更。 |
可能是我们的服务虽然是同时启动,但是启动耗时不一致,消费者和提供者没有在同一时刻注册,所以没有出现这种情况。以上是我本地测试的日志 |
使用5.1的方案解决了问题,但是setStatus的方法里用了updateInstance(serviceId, instance)方法来更新实例状态,如果自定义了groupName,就会报错,而这个解决方案没有对异常做处理,所以看不出来有错误,自己重新了一下setStatus方法就好了 |
在这种极端场景下,确实有这种情况。解决思路的话,可以在对没有获取到元数据的订阅服务列表做一些补偿逻辑(例如:部分订阅服务没有获取到元数据信息则进行重试,重试次数等),应该就能解决掉此问题。 |
你好,我是高良,我已收到你的邮件,麻烦你了
|
这个生产弄我几次事故了。。。我们是k8s 支持自动HPA机制 |
你好,我是高良,我已收到你的邮件,麻烦你了
|
1.问题的直接表现(The direct manifestation of the problem):
org.apache.dubbo.rpc.RpcException: No provider available from registry localhost:9090 for service com.hxy.boot.ticket.articles.api.ArticleService on consumer 192.168.137.1 use dubbo version 2.7.8, please check status of providers(disabled, not registered or in blacklist). at org.apache.dubbo.registry.integration.RegistryDirectory.doList(RegistryDirectory.java:599) at org.apache.dubbo.rpc.cluster.directory.AbstractDirectory.list(AbstractDirectory.java:74) at org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker.list(AbstractClusterInvoker.java:292) at org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker.invoke(AbstractClusterInvoker.java:257) at org.apache.dubbo.rpc.cluster.interceptor.ClusterInterceptor.intercept(ClusterInterceptor.java:47) at org.apache.dubbo.rpc.cluster.support.wrapper.AbstractCluster$InterceptorInvokerNode.invoke(AbstractCluster.java:92) at org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker.invoke(MockClusterInvoker.java:88) at org.apache.dubbo.rpc.proxy.InvokerInvocationHandler.invoke(InvokerInvocationHandler.java:74)
2.问题的直接原因(The direct cause of the problem):
调用服务提供者时,消费者的dubbo的服务目录
org.apache.dubbo.registry.integration.RegistryDirectory
的forbidden
属性 为true
,如下图:When the service provider is called, the
forbidden
property oforg.apache.dubbo.registry.integration.RegistryDirectory
istrue
in consumer side. as shown in the following figure:3.问题的重现(Recurrence of the problem):
这个问题是偶尔出现的,不容易捕捉。经过分析,在服务提供者的
org.apache.dubbo.config.spring.context.DubboBootstrapApplicationListener#onContextRefreshedEvent(ContextRefreshedEvent event)
的 31行打上断点,并且suspend
模式设为Thread
,然后重启服务提供者,就会一直重现此问题。如下图:This problem occurs occasionally and is not easy to catch. After analysis, if a breakpoint is made on line 31 of the service provider's class
org.apache.dubbo.config.spring.context.DubboBootstrapApplicationListener#onContextRefreshedEvent(ContextRefreshedEvent event)
, and the debugsuspend
mode is set tothread
, and then the service provider is restarted, this problem will always recur. as shown in the following figure:4.问题的根本原因(The root cause of the problem):
问题的根本原因是spring cloud alibaba框架启动nacos自动服务注册的时点比启动dubbo服务注册的时点早。前者的启动时点是监听到
WebServerInitializedEvent
事件时(org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration#bind(WebServerInitializedEvent event)
),后者的启动时点是监听到ContextRefreshedEvent
事件时(org.apache.dubbo.config.spring.context.DubboBootstrapApplicationListener#onContextRefreshedEvent(ContextRefreshedEvent event)
)。The root cause of the problem is that the 'spring cloud Alibaba' framework starts Nacos automatic service registration earlier than Dubbo service registration. The starting time of the former is when the 'webserver initialized event' event (
org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration#bind(WebServerInitializedEvent event)
) is heard, while the latter is when the 'contextrefreshedevent' event (org.apache.dubbo.config.spring.context.DubboBootstrapApplicationListener#onContextRefreshedEvent(ContextRefreshedEvent event)
) is monitored.在
spring boot 2.2.x
中ServletWebServerInitializedEvent
事件的发布是在ContextRefreshedEvent
事件之后,如图:In 'spring boot 2.2. X', the 'servlet webserver initialized event' event is published after the 'contextrefreshedevent' event, as shown in the following figure:
但在
spring boot 2.3.x
中改在了ContextRefreshedEvent
事件前,如图:However, in 'spring boot 2.3. X', it is changed before the 'contextrefreshedevent' event, as shown in the following figure:
nacos服务端在处理了服务提供者的注册请求后向订阅者下发了实例变更通知,而在这个过程中提供者自身的dubbo服务暴露有可能还没有完成,最直接的表现就是服务提供者的
com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository
的allExportedURLs
属性中还没有对应的dubbo服务的URL。After processing the registration request of the service provider, the Nacos server sends an instance change notice to the subscriber. In this process, the provider's own Dubbo service exposure may not be completed, and the most direct performance is that: the allexportedurls property of class
com.alibaba.cloud.dubbo.metadata.repository.Dubboservicemetadatarepository
has no URL for the corresponding Dubbo service.在第3条的问题重现里面,当程序跑到断点的时候,通过
jprofiler
查看此时的堆栈信息,可以看到allExportedURLs
属性中没有期望的值。In the problem recurrence in Item 3, when the program runs to a breakpoint, check the stack information through the 'jpprofiler'. You can see that there is no expected value in the 'allexportedurls' attribute.
因为
spring cloud alibaba + dubbo
中dubbo的服务是暴露在本地的com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository
中的allExportedURLs
属性中,不会传到注册中心服务端。所以最终暴露完成以后,nacos服务端无法感知到dubbo服务是否已准备妥当,也无法通知订阅者。这种情况下,提供者发起调用时通过泛化调用DubboMetadataService
接口获取提供者暴露的服务时,从allExportedURLs
中获取到的就是一个空的List<Url>
。然后消费者就会以为是没有提供者,于是在自己本地的dubbo服务目录RegistryDirectory
中 把禁用属性forbidden
的值更新为了true
。Because Dubbo's services in
spring cloud Alibaba + Dubbo
are exposed locally inallexportedurls
property of the classcom.alibaba.cloud . dubbo.metadata.repository.Dubboservicemetadatarepository
. will not be transferred to the registry server.Therefore, after the final exposure is completed, the Nacos server cannot perceive whether the Dubbo service is ready or not, and cannot notify the subscriber.In this case, when a provider initiates a call to obtain the services exposed by the provider through a generalized call to thedubbometadataservice
interface, an emptylist < URL >
is obtained fromallexportedurls
.Then, the consumer will think that there is no provider, so they update the value of disabled attributeforbidden
totrue
in their local Dubbo service directoryregistrydirectory
.这时消费者调用提供者时就出现了第1条中的问题。
At this time, the problem in Article 1 arises when the consumer calls the provider.
5.1 应用端解决方案(Application side solutions):
ApplicationRunner
接口的run
方法中,调用springCloudAlibaba
框架中的NacosServiceRegistry
类的setStatus
方法,更新一下在注册中心的实例状态:After the application is started, in the
run
method of theApplicationrunner
interface, call thesetstatus
method of theNacosserviceregistry
class in thespringcloudalibaba
framework to update the instance status in the registry server.`
@component
public class NacosServiceInstanceUpAndDownOperator implements ApplicationRunner, Closeable {
protected Logger logger = LoggerFactory.getLogger(this.getClass());
}
`
5.2 框架端解决方案的几点意见(Some suggestions on the solution of framework side):
a. 调换
spring cloud
的服务自动注册 和 dubbo服务注册的触发时点(Exchange the trigger time point of automatic service registration of 'spring cloud' and Dubbo service registration)让dubbo服务暴露的启动早于spring cloud的服务自动注册。这样的话就需要修改
spring cloud commons
的源码 和 dubbo 框架的源码,而且动的是根基,感觉不太舒服。Make Dubbo service exposed and automatically register services that start earlier than
spring cloud
.b. spring cloud alibaba 中,dubbo服务暴露完成后向nacos注册中心发布一个更新通知(After the Dubbo service exposure is complete, an update notification is issued to the Nacos registry)
c. spring cloud alibaba 中,添加一个切面,切点为 spring cloud 的服务注册入口,然后在nacos服务注册之前先暴露dubbo服务(Add a aspect to the service registration portal of 'spring cloud'. Then start 'Dubbo' before 'Nacos' service registration to expose Dubbo service:)
spring cloud alibaba
框架中已经有一个现成的切面DubboServiceRegistrationEventPublishingAspect#beforeRegister(Registration registration)
,可以在前置切点里面再加入dubbo服务的暴露就可以了,但对dubbo框架的服务暴露的过程需要做一些调整,避免在ContextRefreshedEvent
事件后做一些重复的工作。The text was updated successfully, but these errors were encountered: