在分布式项目中Dubbo发布服务报No provider available for the service错误。错误信息如下:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dubboServiceTest': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalStateException: Failed to check the status of the service com.bocsoft.ccms.demo.dubbo.service.IDubboServiceTest. No provider available for the service com.bocsoft.ccms.demo.dubbo.service.IDubboServiceTest from the url zookeeper://22.189.25.95:2181/com.alibaba.dubbo.registry.RegistryService?application=access-provider-ccms-test&dubbo=2.8.4&interface=com.bocsoft.ccms.demo.dubbo.service.IDubboServiceTest&methods=getResponseData&pid=8184&side=consumer×tamp=1523930029357 to the consumer 22.189.25.95 use dubbo version 2.8.4
Dubbo默认(缺省)会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止Spring初始化完成,以便上线时,能及早发现问题,默认check=true。
如果你的Spring容器是懒加载的,或者通过API编程延迟引用服务,请关闭check,否则服务临时不可用时,会抛出异常,拿到null引用,如果check=false,总是会返回引用,当服务恢复时,能自动连上。
可以通过check=”false”关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。
1、关闭某个服务的启动时检查:(没有提供者时报错)
<dubbo:reference interface="com.taotao.ItemService" check="false" />
2、关闭所有服务的启动时检查:(没有提供者时报错) 写在定义服务消费者一方
<dubbo:consumer check="false" />
3、关闭注册中心启动时检查:(注册订阅失败时报错)
<dubbo:registry check="false" />
以上方案其实只是关闭了检查,至多不会有报错信息,其实问题还是存在着。应该有一定的排查思路进行排查才能找出问题所在。
先说一下整个系统框架的基本构造:
疑惑:
带着这些问题,进行了相关的验证,最终得出如下结论,先看图,再解释:
1)、用dubbo协议在20880端口暴露服务
在提供者的dubbo配置文件中,一般都配置了<dubbo:protocol name="dubbo" port="20880"/>
,表明用dubbo协议在20880端口暴露服务,当然如果你不配置,dubbo默认使用20880端口暴露服务,所有消费者都是通过20880端口进行,对于消费者而言,提供者服务器8080端口是透明的,也就是说提供者服务器端口号可以任意改变,服务也不会有任何影响,消费者无需关心。
所以上面的异常解决办法是开放20880端口给消费者,而不是8080端口给消费者。
从监控中心可以看到如图:
除了在指定端口上暴露服务之外,还可以在指定ip上暴露服务,配置如下:
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开放给管理员用户,便于通过浏览器监控注册中心服务的情况
总结:注册中心只负责服务注册和目录发布,安全授权,实际的服务访问仍然是两个组件之间的点对点连接完成,这种方式下整个架构下获取更高的性能,同时服务管理平台也不容易成为大并发服务访问下的单点瓶颈
Zookeeper 下载地址: 点我下载
Dubbo-admin 下载地址: 点我下载
Dubbo-monitor 下载地址: 点我下载