dubbo与zk注册中心如何对接,如何做到服务自动发现
先看下consumer端发起调用时的链路流程:
+---------------------------+ +---------------------------+ +---------------------------+
| helloService | | proxy | | InvokerInvocationHandler |
| sayHello +----------> | sayHello +----------> | invoke |
| | | | | proxy method args |
+---------------------------+ +---------------------------+ +-------------+-------------+
|
|
+---------------------------------+
| | |
| +------------v--------------+ |
| | MockClusterInvoker | |
| | invoke | |
| | | |
| +------------+--------------+ |
| | |
| | |
| | |
+---------------------------+ +---------------------------+ | +------------v--------------+ |
| Router | | RegistryDirectory | | | FailoverClusterInvoker | |
| route | <----------+ list | <-----------+ invoke | |
| MockInVokersSelector | | INVOCATION-->List INVOKER | | | | |
+------------+--------------+ +---------------------------+ | +---------------------------+ |
| | |
| +---------------------------------+
| cluster invoke,分布式调用容错机制也是在这做
|
|
|
|
|
+-------------v-------------+ +---------------------------+ +---------------------------+
| RandomLoadBalance | |InvokerDelegate | | ListenerInvokerWrap |
| select +-----------> |invoke +-----------> | invoke |
| List INVOKER-->INVOKER | | | | |
+---------------------------+ +---------------------------+ +---------------------------+
1. 引入zookeeper作为注册中心后,服务查找过程
从建立spring到netty client建立连接的调用栈:
NettyClient.doOpen() line: 66
NettyClient(AbstractClient).(URL, ChannelHandler) line: 94
NettyClient.(URL, ChannelHandler) line: 61
NettyTransporter.connect(URL, ChannelHandler) line: 37
Transporter$Adpative.connect(URL, ChannelHandler) line: not available
Transporters.connect(URL, ChannelHandler...) line: 67
HeaderExchanger.connect(URL, ExchangeHandler) line: 37
Exchangers.connect(URL, ExchangeHandler) line: 102
DubboProtocol.initClient(URL) line: 378
DubboProtocol.getSharedClient(URL) line: 344
DubboProtocol.getClients(URL) line: 321
DubboProtocol.refer(Class, URL) line: 303
ProtocolListenerWrapper.refer(Class, URL) line: 65
ProtocolFilterWrapper.refer(Class, URL) line: 62
Protocol$Adpative.refer(Class, URL) line: not available
RegistryDirectory.toInvokers(List) line: 405
RegistryDirectory.refreshInvoker(List) line: 228
RegistryDirectory.notify(List) line: 196
ZookeeperRegistry(AbstractRegistry).notify(URL, NotifyListener, List) line: 449
ZookeeperRegistry(FailbackRegistry).doNotify(URL, NotifyListener, List) line: 273
ZookeeperRegistry(FailbackRegistry).notify(URL, NotifyListener, List) line: 259
ZookeeperRegistry.doSubscribe(URL, NotifyListener) line: 170
ZookeeperRegistry(FailbackRegistry).subscribe(URL, NotifyListener) line: 189
RegistryDirectory.subscribe(URL) line: 134
RegistryProtocol.doRefer(Cluster, Registry, Class, URL) line: 271
RegistryProtocol.refer(Class, URL) line: 254
ProtocolListenerWrapper.refer(Class, URL) line: 63
ProtocolFilterWrapper.refer(Class, URL) line: 60
Protocol$Adpative.refer(Class, URL) line: not available
ReferenceBean(ReferenceConfig).createProxy() line: 394
ReferenceBean(ReferenceConfig).init() line: 303
ReferenceBean(ReferenceConfig).get() line: 138
ReferenceBean.getObject() line: 65
DefaultListableBeanFactory(FactoryBeanRegistrySupport).doGetObjectFromFactoryBean(FactoryBean, String, boolean) line: 142
整体来说: 先由注册中心的协议处理器处理注册中心的地址,找到所有provider的地址,创建所有invoker,然后再由invoker在真正调用时发起调用。
注册中心的这个也抽象一种协议,由注册中心结合提供者的协议推导出提供者的协议地址,也就是目标端的地址与端口得知了。
每一个接口在zookeeper上都有节点,节点下面是provider,再下面是所有provider的具体地址。
2. netty client的基本步骤
创建channelPipelineFactory,并在这个factory中返回加工好的ChannelPipeline,加工过程包括加入编解码器,连接事件处理组成的netty handler实现
(包括连接建立,断开,请求写出去,)
writeRequested(netty的)-->调用编码器(编码的这个对象中包括了 需要调用的目标接口名 方法名等信息)
(继承SimpleChannelHandler重写逻辑,可以定制channel的读取与写出逻辑)
3. 在使用zookeeper作为注册中心时,如果有provider服务停掉, consumer端如何感知?再次启动刚停掉的provider呢?
provider停掉会触发zk客户端的监听,监听对客户端的invoker列表进行刷新。
再次启动会触发 zk的监听,代码在ZkclientZookeeperClient
public IZkChildListener createTargetChildListener(String path, final ChildListener listener) {
return new IZkChildListener() {
public void handleChildChange(String parentPath, List<String> currentChilds)
throws Exception {
listener.childChanged(parentPath, currentChilds);
}
};
}
然后再触发 com.alibaba.dubbo.registry.support.FailbackRegistry.doNotify(URL, NotifyListener, List)。
com.alibaba.dubbo.registry.integration.RegistryDirectory.refreshInvoker(List), 这是在zk的event线程完成的。
如果有provider停掉了 走一样的监听逻辑
同时,dubbo支持 定时检查provider的状态并进行重连,具体参见
com.alibaba.dubbo.remoting.transport.AbstractClient.initConnectStatusCheckCommand()
reconnectExecutorService.scheduleWithFixedDelay(connectStatusCheckCommand, reconnect, reconnect, TimeUnit.MILLISECONDS);
4. 如果正在发服务的时候,provider停掉了,dubbo是如何处理的?
如果在发服务时,provider停掉了,那么此时会抛出异常,并在FailoverClusterInvoker doInvoke中捕获,
FailoverClusterInvoker支持调用失败时重试(可配置),此时达到再次重试的目的。
5. client在多次调用时,与provider端的连接是建立几次,在prodvider端服务状态有变化时呢?
NettyClient 的doOpen doConnect均在初始化的时候调用,有几个provider就调用几次,真正rpc调用服务的时候是不会再调用open与connect的。
上面这个说法不严格,因为看他发送消息的代码就知道了,每次发消息时还会检查下:
public void send(Object message, boolean sent) throws RemotingException {
if (send_reconnect && !isConnected()){
connect();
}
Channel channel = getChannel();
//TODO getChannel返回的状态是否包含null需要改进
if (channel == null || ! channel.isConnected()) {
throw new RemotingException(this, "message can not send, because channel is closed . url:" + getUrl());
}
channel.send(message, sent);
}
6. 对于多个provider,dubbo默认在哪里选择了一个invoker进行调用的
com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker.select(LoadBalance, Invocation, List<Invoker>, List<Invoker>)。
com.alibaba.dubbo.rpc.filter.EchoFilter@1fd14d74
com.alibaba.dubbo.rpc.filter.ClassLoaderFilter@563e4951
com.alibaba.dubbo.rpc.filter.GenericFilter@4066c471
com.alibaba.dubbo.rpc.filter.ContextFilter@2b175c00
com.alibaba.dubbo.rpc.protocol.dubbo.filter.TraceFilter@3eb81efb
com.alibaba.dubbo.rpc.filter.TimeoutFilter@1ae8bcbc
com.alibaba.dubbo.monitor.support.MonitorFilter@6cdba6dc
com.alibaba.dubbo.rpc.filter.ExceptionFilter@2609b277
dubbo与zk注册中心如何对接,如何做到服务自动发现的更多相关文章
- dubbo支持的注册中心
dubbo支持的注册中心 Dubbo提供的注册中心有如下几种类型可供选择: Multicast注册中心 Zookeeper注册中心 Redis注册中心 Simple注册中心 ZooKeeper是一个开 ...
- Dubbo中多注册中心问题与服务分组
一:注册中心 1.场景 Dubbo 支持同一服务向多注册中心同时注册, 或者不同服务分别注册到不同的注册中心上去, 甚至可以同时引用注册在不同注册中心上的同名服务. 2.多注册中心注册 中文站有些服务 ...
- dubbo可通过指定Url方式绕过注册中心直连指定的服务地址
开发.测试环境可通过指定Url方式绕过注册中心直连指定的服务地址,避免注册中心中服务过多,启动建立连接时间过长,如: <dubbo:reference id="providerServ ...
- dubbo之多注册中心
Dubbo 支持同一服务向多注册中心同时注册,或者不同服务分别注册到不同的注册中心上去,甚至可以同时引用注册在不同注册中心上的同名服务.另外,注册中心是支持自定义扩展的. 多注册中心注册 比如:中文站 ...
- 80%面试官不知道的dubbo → 【redis注册中心】
dubbo的redis注册中心配置和注意事项 配置provider和consumer项目的pom.xml,增加如下2个依赖: org.apache.commons commons-pool2 2.4. ...
- dubbo服务端,dubbo客户端,注册中心(zk)之间的心跳
dubbo客户端和dubbo服务端之间存在心跳,由dubbo客户端主动发起,可参见dubbo源码 HeartbeatTask. dubbo服务端和注册中心(zk)存在心跳,由dubbo服务端发起,这是 ...
- Dubbo使用Zookeeper注册中心
在生产环境下使用最多的注册中心为Zookeeper,当然,Redis也可以做注册中心 一.创建提供者02-provider-zk (1) 导入依赖 https://blog.csdn.net/u012 ...
- dubbo连接zookeeper注册中心因为断网导致线程无限等待问题【转】
最近维护的系统切换了网络环境,由联通换成了电信网络,因为某些过滤规则导致系统连不上zookeeper服务器(应用系统机器在深圳,网络为电信线路,zookeeper服务器在北京,网络为联通线路),因为我 ...
- Dubbo原理解析-注册中心之Zookeeper协议注册中心
下面我们来看下开源dubbo推荐的业界成熟的zookeeper做为注册中心, zookeeper是hadoop的一个子项目是分布式系统的可靠协调者,他提供了配置维护,名字服务,分布式同步等服务.对于z ...
随机推荐
- Wireshark漫谈(一)
可能有人会说,一个软件的安装有什么好谈的,无非就是"同意,同意,同意......是,是,是"诸如此类的选项.的确,Wireshark软件的安装步骤是挺简单的,不过本文不是想谈安装步 ...
- python3发送邮件02(简单例子,带附件)
#!/usr/bin/env python# -*- coding:UTF-8 -*- import osimport smtplibfrom email.header import Headerfr ...
- Mysql的介绍和安装注意
1.Mysql所属公司:Oracle 2.数据库类型:关系型数据库 3.开发语言:C++ 4.版本:企业收费版和社区免费版 5.搭建Mysql环境 点击下一步直到遇到选择数据库编码的时候选择utf-8 ...
- MFC【exe】工程中的文件大致信息(翻译的)
在工程文件夹中有个readme文件,下面是翻译过来的. ======================================================================== ...
- python爬虫之路——初识爬虫原理
爬虫主要做两件事 ①模拟计算机对服务器发起Request请求 ②接收服务器端的Response内容并解析,提取所需的信息 互联网页面错综复杂,一次请求不能获取全部信息.就需要设计爬虫的流程. 本书主要 ...
- 重温Javascript(三)-继承
继承 1.原型链继承 基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法.每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针.让原型 ...
- 陆教授浅谈5G毫米波手机天线技术的发展现状和未来的应用场景
近日,香港城大电子工程学系讲座教授陆贵文教授荣获英国皇家工程院院士荣衔,以表彰他在推动天线研究的卓越贡献.他研发的天线由L形探针馈电微带天线.磁电耦极天线,以至5G毫米波手机天线等技术,均在天线领域影 ...
- React 官方脚手架 create-react-app快速生成新项目
进入新公司已经半年了,各个业务线,技术栈都已经熟悉,工作也已经游刃有余,决定慢下脚步,沉淀积累,回顾一下所用技术栈所包含的基本知识,以及再公司中的实战. 首先回顾新项目搭建 react脚手架目前使用较 ...
- Unity3d 中键值监听方法
unity3d的api中没有负责监听键值的方法,不过unity的input类是通过c#类获取各类监听事件,所以我们可以通过c#类监听,方法如下: void OnGUI() { Event e = Ev ...
- presenting view controller
Present ViewController详解 Present ViewController Modally 一.主要用途 弹出模态ViewController是IOS变成中很有用的一个技术,UIK ...