Netty学习(七):心跳检测机制
创始人
2024-06-02 16:34:20

一、什么是心跳检测机制

所谓心跳, 即在 TCP 长连接中, 客户端和服务器之间定期发送的一种特殊的数据包, 通知对方自己还在线, 以确保 TCP 连接的有效性.

心跳机制主要是客户端和服务端长时间连接时,客户端需要定时发送心跳包来保证自己是存活的,否则一个连接长时间没有作用就会浪费服务端的资源。

二、心跳检测机制的适用场景

长连接的应用场景非常的广泛,比如监控系统,IM系统,即时报价系统,推送服务等等。像这些场景都是比较注重实时性,如果每次发送数据都要进行一次DNS解析,建立连接的过程肯定是极其影响体验。

而长连接的维护必然需要一套机制来控制。比如 HTTP/1.0 通过在 header 头中添加 Connection:Keep-Alive参数,如果当前请求需要保活则添加该参数作为标识,否则服务端就不会保持该连接的状态,发送完数据之后就关闭连接。HTTP/1.1以后 Keep-Alive 是默认打开的。

Netty 是基于 TCP 协议开发的,在四层协议 TCP 协议的实现中也提供了 keepalive 报文用来探测对端是否可用。TCP 层将在定时时间到后发送相应的 KeepAlive 探针以确定连接可用性。

所以,心跳检测一般存在于建立长连接 或者 需要保活的场景。

三、netty的心跳检测机制

基础协议对应用来说不是那么尽善尽美,一个 Netty 服务端可能会面临上万个连接,如何去维护这些连接是应用应该去处理的事情。在 Netty 中提供了 IdleStateHandler 类专门用于处理心跳。

IdleStateHandler 的构造函数如下:

CopypublicIdleStateHandler(long readerIdleTime, long writerIdleTime, long allIdleTime,TimeUnit unit){  
}

说明:

  1. IdleStateHandler 是netty 提供的处理空闲状态的处理器

  1. long readerIdleTime : 表示多长时间没有读, 就会发送一个心跳检测包检测是否连接

  1. long writerIdleTime : 表示多长时间没有写, 就会发送一个心跳检测包检测是否连接

  1. long allIdleTime : 表示多长时间没有读写, 就会发送一个心跳检测包检测是否连接

IdleStateHandler 的文档说明:

triggers an {@link IdleStateEvent} when a {@link Channel} has not performed
read, write, or both operation for a while.

四、Netty心跳检测机制实例

我用即将编写的一个例子来解释什么是心跳检测机制。我将要实现这样的功能:

  1. 当服务器超过3秒没有读时,就提示读空闲

  1. 当服务器超过5秒没有写操作时,就提示写空闲

  1. 当服务器超过7秒没有读或者写操作时,就提示读写空闲

服务端:

public class MyServer {public static void main(String[] args) throws Exception{//创建两个线程组EventLoopGroup bossGroup = new NioEventLoopGroup(1);EventLoopGroup workerGroup = new NioEventLoopGroup(); //8个NioEventLooptry {ServerBootstrap serverBootstrap = new ServerBootstrap();serverBootstrap.group(bossGroup, workerGroup);serverBootstrap.channel(NioServerSocketChannel.class);serverBootstrap.handler(new LoggingHandler(LogLevel.INFO));serverBootstrap.childHandler(new ChannelInitializer() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline();//加入一个netty 提供 IdleStateHandler/**当 IdleStateEvent 触发后 , 就会传递给管道 的下一个handler去处理*通过调用(触发)下一个handler 的 userEventTiggered , 在该方法中去处理 IdleStateEvent(读空闲,写空闲,读写空闲)*/pipeline.addLast(new IdleStateHandler(7000,7000,10, TimeUnit.SECONDS));//加入一个对空闲检测进一步处理的handler(自定义)pipeline.addLast(new MyServerHandler());}});//启动服务器ChannelFuture channelFuture = serverBootstrap.bind(7000).sync();channelFuture.channel().closeFuture().sync();}finally {bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}
}

自定义handler(在该handler中决定如何处理):

public class MyServerHandler extends ChannelInboundHandlerAdapter {/**** @param ctx 上下文* @param evt 事件* @throws Exception*/@Overridepublic void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {if(evt instanceof IdleStateEvent) {//将  evt 向下转型 IdleStateEventIdleStateEvent event = (IdleStateEvent) evt;String eventType = null;switch (event.state()) {case READER_IDLE:eventType = "读空闲";break;case WRITER_IDLE:eventType = "写空闲";break;case ALL_IDLE:eventType = "读写空闲";break;}//这里已经可以知道浏览器所处的空闲是何种空闲,可以执行对应的处理逻辑了System.out.println(ctx.channel().remoteAddress() + "--超时时间--" + eventType);System.out.println("服务器做相应处理..");//如果发生空闲,我们关闭通道// ctx.channel().close();}}
}

相关内容

热门资讯

福建3地入选!全国首届自然资源... 日前,全国首届自然资源节约集约示范县(市)创建成果发布,共推出河北、安徽、山东等11个示范创建省级管...
美国暂停75国签证 (来源:环球时报)转自:环球时报 【#美国暂停75国签证...
截至今天收盘,超三成跨境ETF... 转自:北京日报客户端011月14日,全市场ETF涨多跌少,半数以上基金收涨。主投软件、大数据、金融科...
新疆经济看点丨浩瀚沙海长出生态... 来源:石榴云在塔克拉玛干沙漠边缘,黄沙正悄然蝶变“绿色银行”。2025年,新疆践行“生态产业化、产业...