dubbo心跳机制 (3)
此文已由作者赵计刚授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
二、consumer端心跳机制
- //创建ExchangeClient,对第一次服务发现providers路径下的相关url建立长连接
- -->getClients(URL url)
- -->getSharedClient(URL url)
- -->ExchangeClient exchangeClient = initClient(url)
- -->Exchangers.connect(url, requestHandler)
- -->HeaderExchanger.connect(URL url, ExchangeHandler handler)
- -->new DecodeHandler(new HeaderExchangeHandler(handler)))
- -->Transporters.connect(URL url, ChannelHandler... handlers)
- -->NettyTransporter.connect(URL url, ChannelHandler listener)
- -->new NettyClient(url, listener)
- -->new MultiMessageHandler(HeartbeatHandler(AllChannelHandler(handler)))
- -->getChannelCodec(url)//获取Codec2,这里是DubboCountCodec实例
- -->doOpen()//开启netty客户端
- -->doConnect()//连接服务端,建立长连接
- -->new HeaderExchangeClient(Client client, boolean needHeartbeat)//上述的NettyClient实例,needHeartbeat:true
- -->startHeatbeatTimer()//启动心跳计数器
客户端在initClient(url)中设置了heartbeat参数(默认为60s,用户自己设置的方式见“一”中所讲),如下:
- 1 /**
- 2 * Create new connection
- 3 */
- 4 private ExchangeClient initClient(URL url) {
- 5 ...
- 6 // enable heartbeat by default
- 7 url = url.addParameterIfAbsent(Constants.HEARTBEAT_KEY, String.valueOf(Constants.DEFAULT_HEARTBEAT));
- 8
- 9 ...
- 10
- 11 ExchangeClient client;
- 12 try {
- 13 // connection should be lazy
- 14 if (url.getParameter(Constants.LAZY_CONNECT_KEY, false)) {
- 15 client = new LazyConnectExchangeClient(url, requestHandler);16 } else {
- 17 client = Exchangers.connect(url, requestHandler);
- 18 }
- 19 } catch (RemotingException e) {
- 20 throw new RpcException("Fail to create remoting client for service(" + url + "): " + e.getMessage(), e);
- 21 }
- 22 return client;
- 23 }
与provider类似,来看一下最后开启心跳检测的地方。
- 1 public class HeaderExchangeClient implements ExchangeClient {
- 2 private static final ScheduledThreadPoolExecutor scheduled = new ScheduledThreadPoolExecutor(2, new NamedThreadFactory("dubbo-remoting-client-heartbeat", true));
- 3 private final Client client;
- 4 private final ExchangeChannel channel;
- 5 // heartbeat timer
- 6 private ScheduledFuture<?> heartbeatTimer;
- 7 // heartbeat(ms), default value is 0 , won't execute a heartbeat.
- 8 private int heartbeat;
- 9 private int heartbeatTimeout;
- 10
- 11 public HeaderExchangeClient(Client client, boolean needHeartbeat) {
- 12 if (client == null) {
- 13 throw new IllegalArgumentException("client == null");
- 14 }
- 15 this.client = client;
- 16 this.channel = new HeaderExchangeChannel(client);
- 17 String dubbo = client.getUrl().getParameter(Constants.DUBBO_VERSION_KEY);
- 18 this.heartbeat = client.getUrl().getParameter(Constants.HEARTBEAT_KEY, dubbo != null && dubbo.startsWith("1.0.") ? Constants.DEFAULT_HEARTBEAT : 0);
- 19 this.heartbeatTimeout = client.getUrl().getParameter(Constants.HEARTBEAT_TIMEOUT_KEY, heartbeat * 3);
- 20 if (heartbeatTimeout < heartbeat * 2) {
- 21 throw new IllegalStateException("heartbeatTimeout < heartbeatInterval * 2");
- 22 }
- 23 if (needHeartbeat) {
- 24 startHeatbeatTimer();
- 25 }
- 26 }
- 27
- 28 private void startHeatbeatTimer() {
- 29 stopHeartbeatTimer();
- 30 if (heartbeat > 0) {
- 31 heartbeatTimer = scheduled.scheduleWithFixedDelay(
- 32 new HeartBeatTask(new HeartBeatTask.ChannelProvider() {
- 33 public Collection<Channel> getChannels() {
- 34 return Collections.<Channel>singletonList(HeaderExchangeClient.this);
- 35 }
- 36 }, heartbeat, heartbeatTimeout),
- 37 heartbeat, heartbeat, TimeUnit.MILLISECONDS);
- 38 }
- 39 }
- 40
- 41 private void stopHeartbeatTimer() {
- 42 if (heartbeatTimer != null && !heartbeatTimer.isCancelled()) {
- 43 try {
- 44 heartbeatTimer.cancel(true);
- 45 scheduled.purge();
- 46 } catch (Throwable e) {
- 47 if (logger.isWarnEnabled()) {
- 48 logger.warn(e.getMessage(), e);
- 49 }
- 50 }
- 51 }
- 52 heartbeatTimer = null;
- 53 }
- 54 }
主要看一下startHeartbeatTimer()方法,与provider相同,只是provider是获取NettyServer的所有的NettyChannel,而consumer只是获取当前的对象。
consumer的handler处理链与provider完全相同。
最后来看一下consumer的重连机制:AbstractClient#reconnect
- 1 public void reconnect() throws RemotingException {
- 2 disconnect(); 3 connect();
- 4 }
- 5
- 6 public void disconnect() {
- 7 connectLock.lock();
- 8 try {
- 9 destroyConnectStatusCheckCommand();
- 10 try {
- 11 Channel channel = getChannel();
- 12 if (channel != null) {
- 13 channel.close();
- 14 }
- 15 } catch (Throwable e) {
- 16 logger.warn(e.getMessage(), e);
- 17 }
- 18 try {
- 19 doDisConnect();
- 20 } catch (Throwable e) {
- 21 logger.warn(e.getMessage(), e);
- 22 }
- 23 } finally {
- 24 connectLock.unlock();
- 25 }
- 26 }
- 27
- 28 protected void connect() throws RemotingException {
- 29 connectLock.lock();
- 30 try {
- 31 if (isConnected()) {
- 32 return;
- 33 }
- 34 initConnectStatusCheckCommand();
- 35 doConnect();
- 36 if (!isConnected()) {
- 37 throw new RemotingException(this, "Failed connect to server " + getRemoteAddress() + " from " + getClass().getSimpleName() + " "
- 38 + NetUtils.getLocalHost() + " using dubbo version " + Version.getVersion()
- 39 + ", cause: Connect wait timeout: " + getTimeout() + "ms.");
- 40 } else {
- 41 if (logger.isInfoEnabled()) {
- 42 logger.info("Successed connect to server " + getRemoteAddress() + " from " + getClass().getSimpleName() + " "
- 43 + NetUtils.getLocalHost() + " using dubbo version " + Version.getVersion()
- 44 + ", channel is " + this.getChannel());
- 45 }
- 46 }
- 47 reconnect_count.set(0);
- 48 reconnect_error_log_flag.set(false);
- 49 } catch (RemotingException e) {
- 50 throw e;
- 51 } catch (Throwable e) {
- 52 throw new RemotingException(this, "Failed connect to server " + getRemoteAddress() + " from " + getClass().getSimpleName() + " "
- 53 + NetUtils.getLocalHost() + " using dubbo version " + Version.getVersion()
- 54 + ", cause: " + e.getMessage(), e);
- 55 } finally {
- 56 connectLock.unlock();
- 57 }
- 58 }
代码比较简单,先断连,再连接。
更多网易技术、产品、运营经验分享请点击。
相关文章:
【推荐】 ApiDoc 一键生成注释
dubbo心跳机制 (3)的更多相关文章
- 9.7 dubbo心跳机制
dubbo的心跳机制: 目的:检测provider与consumer之间的connection连接是不是还连接着,如果连接断了,需要作出相应的处理. 原理: provider:dubbo的心跳默认是在 ...
- dubbo心跳机制 (1)
此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. dubbo的心跳机制: 目的:检测provider与consumer之间的connection连接是不是还连 ...
- dubbo心跳机制 (2)
此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 来看一下HeaderExchangeServer.this.getChannels(): 1 p ...
- dubbo之心跳机制
在网络传输中,怎么确保通道连接的可用性是一个很重要的问题,简单的说,在网络通信中有客户端和服务端,一个负责发送请求,一个负责接收请求,在保证连接有效性的背景下,这两个物体扮演了什么角色,心跳机制能有效 ...
- Dubbo之心跳机制 · 房东的小黑
在网络传输中,怎么确保通道连接的可用性是一个很重要的问题,简单的说,在网络通信中有客户端和服务端,一个负责发送请求,一个负责接收请求,在保证连接有效性的背景下,这两个物体扮演了什么角色,心跳机制能有效 ...
- 分析dubbo心跳检测机制
目的: 维持provider和consumer之间的长连接 实现: dubbo心跳时间heartbeat默认是60s,超过heartbeat时间没有收到消息,就发送心跳消息(provider,cons ...
- rabbitmq 的心跳机制&应用
官方文档说: If a consumer dies (its channel is closed, connection is closed, or TCP connection is lost) w ...
- zookeeper心跳机制流程梳理
zookeeper心跳机制流程梳理 Processor链Chain protected void setupRequestProcessors() { RequestProcessor finalPr ...
- 一个Socket连接管理池(心跳机制)
一个Socket连接管理池(心跳机制) http://cuisuqiang.iteye.com/blog/1489661
随机推荐
- Gradle 配置
下载Gradle https://gradle.org/releases/ https://services.gradle.org/distributions/gradle-4.4.1-bin.zip ...
- clone对象的克隆
用一句简单的话来说就是浅拷贝,只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针. 等多 http:/ ...
- DotNetBar笔记
1.TextBoxDropDown 这是一个绝对TMD坑爹的狗屁玩意儿.键盘的四个事件全部不好使.但是这个玩意儿有个好处就是他的DropDownControl属性可以用来制作ComboGrid. 然 ...
- PAT 垃圾箱分布(30分)dijstra
垃圾箱分布 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 大家倒垃圾的时候,都希望垃圾箱距离自己比较近,但是谁都不愿意守着垃圾 ...
- Oracle 文件
参数文件 跟踪文件 告警文件 数据文件 临时文件 控制文件 重做日志文件 密码文件 闪回日志 dum文件 数据泵文件 1参数文件 Parameter file:告诉oracle实例在那里可以找到控制文 ...
- MySQL 学习五 SQL实用函数
0 select now() 显示当前时间. 1 select char_length('andyqan') 显示字符长度. 2 日期格式化 select date_format( ...
- 【转】前端上传组件Plupload使用指南
http://www.cnblogs.com/2050/p/3913184.html Plupload有以下功能和特点: 1.拥有多种上传方式:HTML5.flash.silverlight以及传统的 ...
- Python类(五)-反射
反射即通过字符串映射或修改程序运行时的状态.属性.方法 有4个方法: hasattr(): hasattr(object,string):object为实例化的对象,string为字符串 判断对象ob ...
- AJAX——XMLHttpRequest对象的使用
AJAX是web2.0即动态网页的基础,而XMLHttpRequest对象又是AJAX的核心.XMLHttpRequest对象负责将用户信息以异步通信地发送到服务器端,并接收服务器响应信息和数据 一. ...
- 微信开发准备(二)--springmvc+mybatis项目结构的搭建
转自:http://www.cuiyongzhi.com/post/34.html 前面一篇有说道如何在MyEclipse中搭建maven项目,这里将继续介绍如何在搭建好的基础maven项目中引入我们 ...