dubbo的服务微服务 注册发现现是怎么实现的

调用了dubbo注册的服务,但是dubbo控制台只显示提供者不显示消费者 - 开源中国社区
当前访客身份:游客 [
当前位置:
我用Ubuntu当作服务器,配置了zookeeper和bubbo-admin,然后在windows上用idea注册并调用服务,且成功输出结果,但是访问dubbo控制台只显示服务提供者,但不显示消费者?初学dubbo,很着急,希望大家提供帮助
共有3个答案
<span class="a_vote_num" id="a_vote_num_
应该不会的,你看一下你那边相关的配置,看看是不是消费者用完就关闭了··
<span class="a_vote_num" id="a_vote_num_
同问,我在想是不是少引入了什么包
<span class="a_vote_num" id="a_vote_num_
应该是用完就关闭了,我这边main函数调用完之后也有同样的问题,在main的最后加上while (true) {}后,控制台就能看到消费者了。
更多开发者职位上
有什么技术问题吗?
秋水浮萍的其它问题
类似的话题dubbo注册服务IP解析异常及IP解析源码分析_Java_ThinkSAAS
dubbo注册服务IP解析异常及IP解析源码分析
dubbo注册服务IP解析异常及IP解析源码分析
在使用dubbo注册服务时会遇到IP解析错误导致无法正常访问.
比如: 本机设置的IP为172.16.11.111, 但实际解析出来的是180.20.174.11
这样就导致这个Service永远也无法被访问到, 而调用方一直报错.
当然若发现服务无法访问, 最好先通过dubbo-admin后台排查下注册的服务是否正常.
IP解析异常时的解决方法:
绑定hostname+ip
1. 先查看机器的hostname
2. 修改hosts文件, 增加hostname 172.16.11.111
配置nameserver
排查机器上配置的nameserver是否有问题, 若存在无用的nameserver则直接删掉
在dubbo的配置文件中写死host
&dubbo:protocol host="172.16.11.111"/&
或者在每个provider中绑定host
&dubbo:provider host="172.16.11.111"&
最好不要用第三种方式, 限制太多. 而且如果这样做了就不支持集群了.
dubbo的官网也不建议使用这种方式. 请慎用.
dubbo获取IP源码分析
* 判断host是否为不可用的本地Host
public static boolean isInvalidLocalHost(String host) {
return host == null
|| host.length() == 0
|| host.equalsIgnoreCase("localhost")
|| host.equals("0.0.0.0")
|| (LOCAL_IP_PATTERN.matcher(host).matches());
* 获取本地Host.
* 若address == null ? "127.0.0.1" : InetAddress.getHostAddress();
public static String getLocalHost(){
InetAddress address = getLocalAddress();
return address == null ? LOCALHOST : address.getHostAddress();
private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List&URL& registryURLs) {
//1. 先从ProtocolConfig中取host. 若没有配置则为null
String host = protocolConfig.getHost();
//2. 再从ProviderConfig中取host. 若没有配置则为null
if (provider != null && (host == null || host.length() == 0)) {
host = provider.getHost();
boolean anyhost = false;
//3. 若取出的是本地host, 则继续取host
if (NetUtils.isInvalidLocalHost(host)) {
anyhost = true;
//4. 通过InetAddress的方式获取Host
//默认读取本机hosts中hostname对应的IP
//如: 你在hosts中配置了 leo 172.16.11.111
//则读取的IP就是172.16.11.111
host = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
logger.warn(e.getMessage(), e);
if (NetUtils.isInvalidLocalHost(host)) {
if (registryURLs != null && registryURLs.size() & 0) {
for (URL registryURL : registryURLs) {
Socket socket = new Socket();
//5. 通过Socket的方式获取Host
//一般解析到这里, 都会获取到正确的本地IP, 除非你有多网卡, 或者有VPN, 导致无法正常解析.
SocketAddress addr = new InetSocketAddress(registryURL.getHost(), registryURL.getPort());
socket.connect(addr, 1000);
host = socket.getLocalAddress().getHostAddress();
} finally {
socket.close();
} catch (Throwable e) {}
} catch (Exception e) {
logger.warn(e.getMessage(), e);
//6. 遍历本地网卡, 返回第一个合理的Host
//最后一个大招. 当上述都解析不到时, 则会遍历本地网卡.
//逐个获取IP, 直到有一个合理的IP为止.
if (NetUtils.isInvalidLocalHost(host)) {
host = NetUtils.getLocalHost();
* 遍历本地网卡,返回第一个合理的IP。
* @return 本地网卡IP
public static InetAddress getLocalAddress() {
if (LOCAL_ADDRESS != null)
return LOCAL_ADDRESS;
InetAddress localAddress = getLocalAddress0();
LOCAL_ADDRESS = localA
return localA
* 遍历本地网卡,返回第一个合理的IP。
* @return 本地网卡IP
private static InetAddress getLocalAddress0() {
InetAddress localAddress = null;
localAddress = InetAddress.getLocalHost();
if (isValidAddress(localAddress)) {
return localA
} catch (Throwable e) {
logger.warn("Failed to retriving ip address, " + e.getMessage(), e);
Enumeration&NetworkInterface& interfaces = NetworkInterface.getNetworkInterfaces();
if (interfaces != null) {
while (interfaces.hasMoreElements()) {
NetworkInterface network = interfaces.nextElement();
Enumeration&InetAddress& addresses = network.getInetAddresses();
if (addresses != null) {
while (addresses.hasMoreElements()) {
InetAddress address = addresses.nextElement();
if (isValidAddress(address)) {
} catch (Throwable e) {
logger.warn("Failed to retriving ip address, " + e.getMessage(), e);
} catch (Throwable e) {
logger.warn("Failed to retriving ip address, " + e.getMessage(), e);
} catch (Throwable e) {
logger.warn("Failed to retriving ip address, " + e.getMessage(), e);
logger.error("Could not get local host ip address, will use 127.0.0.1 instead.");
return localA
内容来源:
PHP开发框架
开发工具/编程工具
服务器环境
ThinkSAAS商业授权:
ThinkSAAS为用户提供有偿个性定制开发服务
ThinkSAAS将为商业授权用户提供二次开发指导和技术支持
让ThinkSAAS更好,把建议拿来。
开发客服微信Dubbo 服务暴露注册流程 - 蝈蝈俊 - 博客园
posts - 483, comments - 148, trackbacks - 0, articles - 0
Dubbo的应用会在启动时完成服务注册或订阅(不论是生产者,还是消费者)如下图所示。
图中小方块Protocol, Cluster, Proxy, Service, Container, Registry, Monitor代表层或模块,蓝色的表示与业务有交互,绿色的表示只对Dubbo内部交互。
图中背景方块Consumer, Provider, Registry, Monitor代表部署逻辑拓普节点。
图中蓝色虚线为初始化时调用,红色虚线为运行时异步调用,红色实线为运行时同步调用。
图中只包含RPC的层,不包含Remoting的层,Remoting整体都隐含在Protocol中。
整个服务初始化的过程细节如下:
在配置文件中,所有dubbo的标签,都统一用DubboBeanDefinitionParser进行解析,基于一对一属性映射,将XML标签解析为Bean对象。
相关信息可以参考: Dubbo中对Spring配置标签扩展()
以 dubbo-demo-provider 为例, 它的配置文件如下:
&beans xmlns=&
&#160;&#160;&#160; xmlns:xsi=&
&#160;&#160;&#160; xmlns:dubbo=&
&#160;&#160;&#160; xsi:schemaLocation=&
&#160;&#160;&#160;
&#160;&#160;&#160; &#160;&#160;&#160; &bean id=&demoService& class=&com.alibaba.dubbo.demo.provider.DemoServiceImpl& /&
&#160;&#160;&#160; &#160;&#160;&#160; &dubbo:service interface=&com.alibaba.dubbo.demo.DemoService& ref=&demoService& /&
&#160;&#160;&#160; &/beans&
com.alibaba.dubbo.demo.provider.DemoServiceImpl 是服务实现类。
com.alibaba.dubbo.demo.DemoService 是服务需要实现的接口。
配置文件的解析过程
基于dubbo.jar内的META-INF/spring.handlers配置,Spring在遇到dubbo名称空间时,会回调DubboNamespaceHandler。
所有dubbo的标签,都统一用DubboBeanDefinitionParser进行解析,基于一对一属性映射,将XML标签解析为Bean对象。
每个service方法的配置会解析成对应的 com.alibaba.dubbo.config.spring.ServiceBean&T& 类的实例。
具体请参考:Dubbo中对Spring配置标签扩展 ()
配置文件对应的配置类的关系图如下:
根据 Spring Bean 的生命周期()
在 afterPropertiesSet 后, 会调用到 ServiceConfig.export() 。
生产者在ServiceConfig.export()或消费者在ReferenceConfig.get()初始化时,将Bean对象转换URL格式,所有Bean属性转成URL的参数。
它的调用堆栈如下图:
然后将URL传给Protocol扩展点,基于扩展点的Adaptive机制,根据URL的协议头,进行不同协议的服务暴露或引用。
public interface Protocol {
* 暴露远程服务:&br&
* 1. 协议在接收请求时,应记录请求来源方地址信息:RpcContext.getContext().setRemoteAddress();&br&
* 2. export()必须是幂等的,也就是暴露同一个URL的Invoker两次,和暴露一次没有区别。&br&
* 3. export()传入的Invoker由框架实现并传入,协议不需要关心。&br&
* @param &T& 服务的类型
* @param invoker 服务的执行体
* @return exporter 暴露服务的引用,用于取消暴露
* @throws RpcException 当暴露服务出错时抛出,比如端口已占用
&T& Exporter&T& export(Invoker&T& invoker) throws RpcE[引用]Dubbo之旅--注册中心
[引用]Dubbo之旅--注册中心
在介绍Dubbo的内部逻辑的时候提到很多次注册中心的概念.实现注册中心的有很多,主要是以下四个注册中心分别是:&Multicast注册中心Zookeeper注册中心Redis注册中心Simple注册中心&&&&&&&这里将对注册中心的一个实现Zookeeper跟大家分享,因为Zookeeper是应用比较多,也是我们项目中实际用到的注册中心.&&&&&&&&&&&&&ZooKeeper&是一个为分布式应用所设计的分布的、开源的协调服务。分布式的应用可以建立在同步、配置管理、分组和命名等服务的更高级别的实现的基础之上。&ZooKeeper&意欲设计一个易于编程的环境,它的文件系统使用我们所熟悉的目录树结构。&ZooKeeper&使用&Java&所编写,但是支持&Java&和C&两种编程语言。&&&&协调服务是非常容易出错的,&同时也很难恢复正常,例如,协调服务很容易处于竞态以至于出现死锁。&ZooKeeper&的目的是为了减轻分布式应用程序所承担的协调任务。&&&&&&ZooKeeper命名空间&&&&&&提供的命名空间与标准的文件系统非常相似。一个名称是由通过斜线分隔开的路径名序列所组成的。ZooKeeper中的每一个节点是都通过路径来识别。下图是Zookeeper中节点的数据模型,这种树形结构的命名空间操作方便且易于理解。&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&图:ZooKeeper层次命名空间&&&&&&&&&&&接着上图中,我们需要了解一下ZooKeeper中的节点和临时节点&&&&&&&&&ZooKeeper的节点是通过像树一样的结构来进行维护的,并且每一个节点通过路径来标示以及访问。除此之外,每一个节点还拥有自身的一些信息,包括:数据、数据长度、创建时间、修改时间等等。&&&&&&&&&&从这样一类既含有数据,又作为路径表标示的节点的特点中,可以看出,ZooKeeper的节点既可以被看做是一个文件,又可以被看做是一个目录,它同时具有二者的特点。为了简单我们可以Znode来表示所讨论的ZooKeeper节点。&&&&&&&&&具体地说,Znode维护着数据、ACL(access controllist,访问控制列表)、时间戳等交换版本号等数据结构,它通过对这些数据的管理来让缓存生效并且令协调更新。每当Znode中的数据更新后它所维护的版本号将增加,这非常类似于数据库中计数器时间戳的操作方式。&&&&&&&&&另外Znode还具有原子性操作的特点:命名空间中,每一个Znode的数据将被原子地读写。读操作将读取与Znode相关的所有数据,写操作将替换掉所有的数据。除此之外,每一个节点都有一个访问控制列表,这个访问控制列表规定了用户操作的权限。&&&&&&&ZooKeeper中同样存在临时节点。这些节点与session同时存在,当session生命周期结束,这些临时节点也将被删除。临时节点在某些场合也发挥着非常重要的作用。&&&&&&&&&&了解了Zookeeper的命名空间和节点之后我们需要跟上一篇文章中提到的内部逻辑联系起来.在上篇介绍到的内部流程中,拿到这里看看Zookeeper是如何处理的,流程如下图:&&&&& &1 &当服务提供者启动时,Zookeeper向/dubbo/com.foo.BarService/providers目录下写入自己的URL地址。&& &2 当服务消费者启动时,这时候有两个动作:订阅/dubbo/com.foo.BarService/providers目录下的提供者URL地址。并向/dubbo/com.foo.BarService/consumers目录下写入自己的URL地址。&& 3当监控中心启动时,订阅/dubbo/com.foo.BarService目录下的所有提供者和消费者URL地址。&&&&&&&以上内容算是对Zookeeper进行了一个入门级的了解,如果想深入对其了解的话可以参考一下文章:&&&&&&
发表评论:
TA的最新馆藏

我要回帖

更多关于 微服务 注册发现 的文章

 

随机推荐