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
随机推荐
- python之 python 起源、语言特点
一. 1.1 什么是 PythonPython 是一门优雅而健壮的编程语言,它继承了传统编译语言的强大性和通用性,同时也借鉴了简单脚本和解释语言的易用性.它可以帮你完成工作,而且一段时间以后,你还能 ...
- 第十篇 javascript基础语法
1)基本概念 a) 语句(statement)是为了完成某种任务而进行的操作,语句以分号结尾,一个分号就表示一个语句结束.:如:var a = 1; b) 表达式(expression),指一个为了得 ...
- HDU1272(并查集判图连通)
小希的迷宫 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
- springboot+springcloud config
参考:sorry,全找不到了,当时没记录,最后后知后觉觉得应该记录,所以后面的都有在asfood父项目中的doc文件夹下记录,望见谅. 1. springconfig server 1.1. pom. ...
- linux指令 apt-grt指令使用
apt-get 是linux的一条指令,主流的linux版本Debian和ubuntu都使用apt-get来安装软件.那么,需安装的软件都放在哪里呢??? apt-get 利用软件安装源来安装软件,其 ...
- PostgreSQL服务器参数配置
服务器配置1 设置参数1.1 参数名称和值所有参数名都是大小写不敏感的.每个参数都可以接受五种类型之一的值: 布尔.字符串.整数. 浮点数或枚举.布尔: 值可以被写成 on, off, true, f ...
- IDEA编译器如何去掉注释中参数错误的提示
在使用idea的导入别人的项目的时候经常会在方法注释中出现参数错误的提示,这时我们可以参考下面的配置,将方法注释中的参数错误的提示,更新为警告提示~~ 具体使用方法,参考下图~
- PDM中列举所有含取值范围、正则表达式约束的字段
Option Explicit ValidationMode = True InteractiveMode = im_Batch Dim mdl '当前model '获取当前活 ...
- windows服务编写和“以管理员运行”程序的方法
本文将首先解释如何 创建 一个定期查询可用物理内存并将结果写入某个文本文件的服务.然后指导你完成生成,安装和实现服务的整个过程. 第一步:主函数和全局定义 首先,包含所需的头文件.例子要调用 Win3 ...
- Rozor视图(c#代码与html混合编程原则)
(1)大括号的匹配原则(就近原则){} (2)html标签有截断c#代码的功能 @*服务器端的注释*@ <!--客户端注释-->