dubbo+zookeeper与提供者、消费者之间端口通信问题(No provider available for the service)

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> dubbo+zookeeper与提供者、消费者之间端口通信问题(No provider available for the service)

一、异常信息分析


Failed to check the status of the service com.sihai.service.ItemService. No provider available for the service com.sihai.service.ItemService from the url zookeeper://192.168.131.133:2181/com.alibaba.dubbo.registry.RegistryService?application=sihai-manager-web&dubbo=2.5.3&interface=com.sihai.service.ItemService&methods=getItemById&pid=18216&revision=0.0.1-SNAPSHOT&side=consumer&timestamp=1519567537377 to the consumer 192.168.131.1 use dubbo version 2.5.3
    at com.alibaba.dubbo.config.ReferenceConfig.createProxy(ReferenceConfig.java:420)
    at com.alibaba.dubbo.config.ReferenceConfig.init(ReferenceConfig.java:300)
    at com.alibaba.dubbo.config.ReferenceConfig.get(ReferenceConfig.java:138)
    at com.alibaba.dubbo.config.spring.ReferenceBean.getObject(ReferenceBean.java:65)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:168)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:103)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1585)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:254)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1192)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:545)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
    at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:668)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:634)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:682)
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:553)
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:494)
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
    at javax.servlet.GenericServlet.init(GenericServlet.java:160)
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1280)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1193)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1088)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5176)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5460)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

异常分析:

上面的异常,Caused by的前半部分有的说bean创建失败,有的说属性自动装配失败,但后半部分都比较统一,都是:No provider available for the service ……,服务没有可以使用的提供者,完整意思就是:对于消费者(consumer-ip)而言,在zookeeper注册中心(zookeeper-url)没有可用的提供者(No provider available for the service com.test.rpc.OrgRPC),消费者访问提供者的时候失败了;

因为消费者没有变,变化的是向注册中心注册的提供者由开发服务器变更为测试服务器,同时由于之前处理过因为【No route to host】引起的异常,所以想到可能是提供者端口不通造成的,然后从消费者服务器telnet 提供者ip 20880端口,果然如此。

网上解决办法整合:

1、将提供者服务器的 20880端口开放给消费者服务器ip,重新启动消费者服务器,正常启动。 2、可能是你没有在 spring-service的配置文件中没有提供服务。 3、dubbo配置的时候需要一个注册中心 这个注册中心主要起的作用为服务做配置 每当一个服务生产者去注册服务时候 会把这个生产者的ip跟端口号丢上去注册中心 而服务的消费方就会从注册中心拿到服务的ip跟端口号 放在本地文件中 底层调用netty访问服务 昨天跟同事一块调程序 他开服务生产者 我开服务调用者 后边就出 Failed to check the status of the service . No provider available for the service 这个问题 然后就去 dubboadmin上边看 服务正常启动 但是服务提供者的ip是192.168.83.1 是同事搞虚拟机的时候弄虚拟网卡的地址 所以我这边消费方拿到他的虚拟网卡ip才访问不到服务 于是乎 禁用虚拟网卡 问题解决

我的解决方法:主要的报错信息 No provider available for the service com.sihai.service.ItemService from the url zookeeper://192.168.131.133:2181/com.alibaba.dubbo.registry.RegistryService?application=sihai-manager-web&dubbo=2.5.3&interface=com.sihai.service.ItemService&methods=getItemById&pid=18216&revision=0.0.1-SNAPSHOT&side=consumer&timestamp=1519567537377 to the consumer 192.168.131.1 use dubbo version 2.5.3这个问题的报错是没有服务的提供者,因为我的项目是service层给controller层提供服务,所以service 层是服务的提供者,因为报错是没有服务的提供者,所以问题就在service的dubbo的服务有没有正常的提供,最后发现自己的spring的web.xml的文件忘记加入加载spring容器的配置了,导致不能正常的发布服务!所以下次出现问题的时候,多看看异常信息,这个问题导致我花了几个小时,结果网上的解答都没有解决我的问题,最后还是自己看报错解决了!

##二、dubbo+zookeeper与提供者provider、消费者consumer之间通信过程

先说一下整个系统框架的基本构造:

  • zookeeper作为注册中心,使用单独服务器,占用2181端口 - dubbo-admin作为监控中心,与zookeeper使用相同服务器,tomcat部署占用8080端口 - provider作为提供者,使用单独服务器,tomcat部署占用8080端口,使用dubbo协议开放20880端口 - consumer作为消费者,使用单独服务器,tomcat部署占用8080端口
    再看上面的异常,虽然解决了,是不是有人和我一样有一些问题想不通:
  • provider服务器端口是8080,为什么telnet测试以及解决方案中开放的端口却是20880? - 要说dubbo协议开放了20880端口,那8080端口应该也开放啊? - zookeeper、provider、consumer之间端口开放和屏蔽情况到底是怎么回事?
    带着这些问题,进行了相关的验证,最终得出如下结论,先看图,再解释:
这里写图片描述

##1)、用dubbo协议在20880端口暴露服务

在提供者的dubbo配置文件中,一般都配置了 <dubbo:protocol name="dubbo" port="20880"/>,表明用dubbo协议在20880端口暴露服务,当然如果你不配置,dubbo默认使用20880端口暴露服务,所有消费者都是通过20880端口进行,对于消费者而言,提供者服务器8080端口是透明的,也就是说提供者服务器端口号可以任意改变,服务也不会有任何影响,消费者无需关心。

所以上面的异常解决办法是开放20880端口给消费者,而不是8080端口给消费者。

从监控中心可以看到如图:

这里写图片描述

除了在指定端口上暴露服务之外,还可以在指定ip上暴露服务,配置如下:


<dubbo:protocol name="dubbo" host="10.1.22.2" port="20880" />

##2)、端口开放情况

zookeeper作为注册中心,provider注册服务、consumer订阅服务、dubbo-admin监控服务,所以zookeeper注册中心的2181端口需要向provider、consumer、dubbo-admin开放;

一般情况下,dubbo-admin监控中心与zookeeper注册中心部署在相同的服务器上,zookeeper可以不考虑端口开放给dubbo-admin的情况;

consumer订阅服务,即拿到了provider在20880端口暴露的服务,当consumer请求服务时,直接从consumer跳到provider,而不是consumer到zookeeper再到provider,所以provider的20880无需开放给zookeeper;

同理,provider响应服务时,也是直接从provider到consumer,而不是provider到zookeeper再到consumer,所以consumer的8080无需开放给zookeeper;

zookeeper注册中心是完全被动的。

##三、总结一下:

  • zookeeper的2181开放给provider、consumer、dubbo-admin - provider的20880开放给所有consumer,但8080服务器端口可以完全屏蔽 - consumer的8080开放给所有provider - dubbo-admin的8080开放给管理员用户,便于通过浏览器监控注册中心服务的情况 - 总结:注册中心只负责服务注册和目录发布,安全授权,实际的服务访问仍然是两个组件之间的点对点连接完成,这种方式下整个架构下获取更高的性能,同时服务管理平台也不容易成为大并发服务访问下的单点瓶颈

注意:当出现错误时,还是多看看后台的异常信息,说不定就解决了,可以省去很多不必要的麻烦,浪费了很多时间!

参考:http://blog.csdn.net/javaloveiphone/article/details/52290292

点个赞,看一看,好习惯!本文 GitHub 已收录,这是我花了 3 个月总结的一线大厂 Java 面试总结,本人已拿大厂 offer。 另外,原创文章首发在我的个人博客:,欢迎访问。

最后,再分享我历时三个月总结的 Java 面试 + Java 后端技术学习指南,这是本人这几年及春招的总结,已经拿到了大厂 offer,整理成了一本电子书,拿去不谢,目录如下:

现在免费分享大家,在下面我的公众号 程序员的技术圈子 回复 面试 即可获取。

有收获?希望老铁们来个三连击,给更多的人看到这篇文章

1、老铁们,关注我的原创微信公众号「程序员的技术圈子」,专注于 Java、数据结构和算法、微服务、中间件等技术分享,保证你看完有所收获。

2、给俺点个赞呗,可以让更多的人看到这篇文章,顺便激励下我继续写作,嘻嘻。

3、另外,原创文章首发在我的个人博客:,欢迎访问。

点赞是对我最大的鼓励 ↓↓↓↓↓↓

原文地址:https://sihai.blog.csdn.net/article/details/79372082

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> dubbo+zookeeper与提供者、消费者之间端口通信问题(No provider available for the service)


 上一篇
如何生成安全的密码 Hash——MD5, SHA, PBKDF2, BCrypt 如何生成安全的密码 Hash——MD5, SHA, PBKDF2, BCrypt
. 一、前言密码 Hash 值的产生是将用户所提供的密码通过使用一定的算法计算后得到的加密字符序列。在 Java 中提供很多被证明能有效保证密码安全的 Hash 算法实现,我将在这篇文章中讨论其中的部分算法。 需要注意的是,一旦生成密码的
2021-04-04
下一篇 
ubuntu下使用filezilla上传文件权限问题(open for write—— permission denied) ubuntu下使用filezilla上传文件权限问题(open for write—— permission denied)
今天在使用filezilla连接虚拟机中的ubuntu的时候出现上次出错,错误详情为: open for write: permission denied 看完错误大概知道和权限有问题,再次查看虚拟机,我们使用以下命令给我们需要放入
2021-04-04