Dubbo之心跳机制 · 房东的小黑
在网络传输中,怎么确保通道连接的可用性是一个很重要的问题,简单的说,在网络通信中有客户端和服务端,一个负责发送请求,一个负责接收请求,在保证连接有效性的背景下,这两个物体扮演了什么角色,心跳机制能有效的保证连接的可用性,那它的机制是什么,下文中将会详细讲解。
在网络传输中,怎么确保通道连接的可用性是一个很重要的问题,简单的说,在网络通信中有客户端和服务端,一个负责发送请求,一个负责接收请求,在保证连接有效性的背景下,这两个物体扮演了什么角色,心跳机制能有效的保证连接的可用性,那它的机制是什么,下文中将会详细讲解。
首先讲一下TCP,在dubbo中的通信是基于TCP的,TCP本身并没有长短连接的区别,在短连接中,每次通信时,都会创建Socket,当该次通信结束后,就会调用socket.close();而在长连接中,每次通信完毕后,不会关闭连接,这样就可以做到连接的复用,长连接的好处是省去了创建连接时的耗时。那么如何确保连接的有效性呢,在TCP中用到了KeepAlive机制,keepalive并不是TCP协议的一部分,但是大多数操作系统都实现了这个机制,在一定时间内,在链路上如果没有数据传送的情况下,TCP层将会发送相应的keepalive探针来确定连接可用性,探测失败后重试10次(tcp_keepalive_probes),每次间隔时间为75s(tcp_keepalive_intvl),所有探测失败后,才认为当前连接已经不可用了。
KeepAlive机制是在网络层保证了连接的可用性,但在应用层我们认为这还是不够的。
- KeepAlive的报活机制只有在链路空闲的情况下才会起作用,假如此时有数据发送,且物理链路已经不通,操作系统这边的链路状态还是E STABLISHED,这时会发生TCP重传机制,要知道默认的TCP超时重传,指数退避算法也是一个相当长的过程。
- KeepAlive本身是面向网络的,并不是面向于应用的,可能是由于本身GC问题,系统load高等情况,但网络依然是通的,此时,应用已经失去了活性,所以连接自然认为是不可用的。
应用层的连接可用性:心跳机制
如何理解应用层的心跳?简单的说,就是客户端会开启一个定时任务,定时对已经建立连接的对端应用发送请求,服务端则需要特殊处理该请求,返回响应。如果心跳持续多次没有收到响应,客户端会认为连接不可用,主动断开连接。
客户端如何得知请求失败了?
在失败的场景下,服务端是不会返回响应的,所以只能在客户端自身上设计了。
当客户端发起一个RPC请求时,会设置一个超时时间client_timeout,同时它也会开启一个延迟的client_timeout的定时器。当接收到正常响应时,会移除该定时器;而当计时器倒计时完毕后,还没有被移除,则会认为请求超时,构造一个失败的响应传递给客户端。
连接建立时创建定时器
HeaderExchangeClient类
1 |
public (Client client, boolean needHeartbeat) {
|
创建了一个HashedWheelTimer开启心跳检测,这是 Netty 所提供的一个经典的时间轮定时器实现。
HeaderExchangeServer也同时开启了定时器,代码逻辑和上述差不多。
开启两个定时任务
1 |
private void startHeartbeatTimer() {
|
在该方法中主要开启了两个定时器
- HeartbeatTimerTask 主要是定时发送心跳请求
- ReconnectTimerTask 主要是心跳失败后处理重连,断连的逻辑
旧版的心跳处理HeartBeatTask类
1 |
final class HeartBeatTask implements Runnable {
private static final Logger logger = LoggerFactory.getLogger(HeartBeatTask.class);
/**
|
它首先遍历所有的Channel,在服务端对用的是所有客户端连接,在客户端对应的是服务端连接,判断当前TCP连接是否空闲,如果空闲就发送心跳报文,判断是否空闲,根据Channel是否有读或写来决定,比如一分钟内没有读或写就发送心跳报文,然后是处理超时的问题,处理客户端超时重新建立TCP连接,目前的策略是检查是否在3分钟内都没有成功接受或发送报文,如果在服务端检测则就会主动关闭远程客户端连接。
新版本的心跳机制
定时任务一: 发送心跳请求
在新版本下,去除了HeartBeatTask类,添加了HeartbeatTimerTask和ReconnectTimerTask类
1 |
public class HeartbeatTimerTask extends AbstractTimerTask {
private static final Logger logger = LoggerFactory.getLogger(HeartbeatTimerTask.class);
private final int heartbeat;
HeartbeatTimerTask(ChannelProvider channelProvider, Long heartbeatTick, int heartbeat) {
|
Dubbo采取的是双向心跳设计,即服务端会向客户端发送心跳,客户端也会向服务端发送心跳,接收的一方更新lastread字段,发送的一方更新lastWrite字段,超过心跳间隙的时间,便发送心跳请求给对端。
定时任务二: 处理重连和断连
1 |
public class ReconnectTimerTask extends AbstractTimerTask {
private static final Logger logger = LoggerFactory.getLogger(ReconnectTimerTask.class);
private final int idleTimeout;
public ReconnectTimerTask(ChannelProvider channelProvider, Long heartbeatTimeoutTick, int idleTimeout) {
|
不同类型处理机制不同,当超过设置的心跳总时间后,客户端选择的是重新连接,服务端是选择直接断开连接。
心跳改进方案
Netty对空闲连接的检测提供了天然的支持,使用IdleStateHandler可以很方便的实现空闲检测逻辑。
1 |
public IdleStateHandler(long readerIdleTime, long writerIdleTime, long allIdleTime, TimeUnit unit){}
|
- readerIdleTime: 读超时的时间
- writerIdleTime: 写超时的时间
- allIdleTime: 所有类型的超时时间
客户端和服务端配置
客户端:
1
2
3
4
5
6bootstrap.handler(new ChannelInitializer<NioSocketChannel>() { protected void initChannel(NioSocketChannel ch) throws Exception {
ch.pipeline().addLast("clientIdleHandler", new IdleStateHandler(60, 0, 0));
}
});
服务端:
1 |
serverBootstrap.childHandler(new ChannelInitializer<NioSocketChannel>() {
protected void initChannel(NioSocketChannel ch) throws Exception {
|
从上面看出,客户端配置了read超时为60s,服务端配置了write/read超时未200s,
空闲超时逻辑-客户端
对于空闲超时的处理逻辑,客户端和服务端是不同的,首先来看客户端的:
1 |
@Override |
检测到空闲超时后,采取的行为是向服务端发送心跳包,
1 |
public void sendHeartBeat() {
|
构造一个心跳包发送到服务端,接受响应结果
- 响应成功,清除请求失败标记
- 响应失败,心跳失败标记+1,如果超过配置的失败次数,则重新连接
空闲超时逻辑 - 服务端
1
2
3
4
5
6
7
8@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof IdleStateEvent) {
channel.close();
} else {
super.userEventTriggered(ctx, evt);
}
}
服务端直接关闭连接。
Dubbo之心跳机制 · 房东的小黑的更多相关文章
- dubbo之心跳机制
在网络传输中,怎么确保通道连接的可用性是一个很重要的问题,简单的说,在网络通信中有客户端和服务端,一个负责发送请求,一个负责接收请求,在保证连接有效性的背景下,这两个物体扮演了什么角色,心跳机制能有效 ...
- 9.7 dubbo心跳机制
dubbo的心跳机制: 目的:检测provider与consumer之间的connection连接是不是还连接着,如果连接断了,需要作出相应的处理. 原理: provider:dubbo的心跳默认是在 ...
- dubbo心跳机制 (1)
此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. dubbo的心跳机制: 目的:检测provider与consumer之间的connection连接是不是还连 ...
- dubbo心跳机制 (3)
此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 二.consumer端心跳机制 //创建ExchangeClie ...
- 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
- ESFramework 开发手册(07) -- 掉线与心跳机制(转)
虽然我们前面已经介绍完了ESFramework开发所需掌握的各种基础设施,但是还不够.想要更好地利用ESFramework这一利器,有些背景知识是我们必须要理解的.就像本文介绍的心跳机制,在严峻的In ...
- 判定生死的心跳机制 --ESFramework 4.0 快速上手(07)
在Internet上采用TCP进行通信的系统,都会遇到一个令人头疼的问题,就是"掉线".而"TCP掉线"这个问题远比我们通常所能想象的要复杂的多 -- 网络拓扑 ...
随机推荐
- 小白学习之pytorch框架(6)-模型选择(K折交叉验证)、欠拟合、过拟合(权重衰减法(=L2范数正则化)、丢弃法)、正向传播、反向传播
下面要说的基本都是<动手学深度学习>这本花书上的内容,图也采用的书上的 首先说的是训练误差(模型在训练数据集上表现出的误差)和泛化误差(模型在任意一个测试数据集样本上表现出的误差的期望) ...
- lower_bound()和upper_bound()用法详解
lower_bound( )和upper_bound( )都是利用二分查找的方法在一个排好序的数组中进行查找的. lower_bound( begin,end,num):从数组的begin位置到end ...
- BBS数据库设计
BBS数据库设计 一.BBS数据库设计 # models.py from django.db import models # Create your models here. from django. ...
- HTML5中的data-*属性
data-* 属性包括两部分: 属性名不应该包含任何大写字母,并且在前缀 "data-" 之后必须有至少一个字符: 属性值可以是任意字符串: 注释:用户代理会完全忽略前缀为 &qu ...
- Pytorch——BERT 预训练模型及文本分类
BERT 预训练模型及文本分类 介绍 如果你关注自然语言处理技术的发展,那你一定听说过 BERT,它的诞生对自然语言处理领域具有着里程碑式的意义.本次试验将介绍 BERT 的模型结构,以及将其应用于文 ...
- jexus+.netcore+identityserver4 部署支持ssl(https)
硬件环境: 在阿里云购买了一个centos 7 64 位服务器 软件: jexus ,dotnet core sdk 第一步安装dotnet core sdk: 先安装dotnet core sdk ...
- RDD(五)——action
reduce(func) 通过func函数聚集RDD中的所有元素并得到最终的结果,先聚合分区内数据,再聚合分区间数据.Func函数决定了聚合的方式. def main(args: Array[Stri ...
- windows下pip的安装
安装地址:https://pypi.python.org/pypi/pip#downloads 下载完成后,找到文件并进行解压,找到下面路径. 打开cmd,cd到当前目录下,然后执行下面命令: pyt ...
- Linux基础篇七:Linux的命令执行
首选区分内置命令和外置命令: 内置命令:shell程序自带的命令,系统内核一启动就可以使用的命令 外置命令:在系统PATH变量路径下的命令 如何查看一个命令是内置命令还是外置命令: type -a c ...
- Normally Distributed|
6.1Introducing Normally Distributed Variables Why the word “normal”? Because, in the last half of th ...