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 https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了 3 个月总结的一线大厂 Java 面试总结,本人已拿大厂 offer。
另外,原创文章首发在我的个人博客:blog.ouyangsihai.cn,欢迎访问。

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

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

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

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

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

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

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

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页
实付 9.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值