剖析目的
Netty 作为一个网络框架,提供了诸多功能,比如编码解码等,Netty 还提供了非常重要的一个服务----心跳机制 heartbeat.通过心跳检査对方是否有效,这是 RPC 框架中是必不可少的功能。下面我们分析一下 Netty 内部心跳服务源码实现。
源码剖析
Netty 提供了 IdleStateHandler ,ReadTimeoutHandler,WriteTimeoutHandler 三个Handler 检测连接的有效性重点分析 IdleStateHandler
序号 | 名称 | 作用 |
1 | IdleStateHandler | 当连接的空闲时间(读或者写)太长时,将会触发一个IdleStateEvent 事件。然后,你可以通过你的 ChannellnboundHandler 中重写 userEventTrigged 方法来处理该事件。 |
2 | ReadTimeoutHandler | 如果在指定的事件没有发生读事件,就会抛出这个异常,并自动关闭这个连接。你可以在exceptionCaught 方法中处理这个异常。 |
3 | WriteTimeoutHandler | 当一个写提作不能在一定的时间内完成时,抛出此异常,并关闭连接,你同样可以在exceptionCaught 方法中处理这个异常。 |
ReadTimeout 事件和 WriteTimeout 事件都会自动关闭连接,而且,属于异常处理
IdleStateHandler 分析
4 个属性
private final boolean observeOutput, //是否考虑出站时较慢的情况。默认值是 false
private final long readerldleTimeNanos://读事件空闲时间,0 则禁用事件
private final long writerldleTimeNanos;//写事件空闲时间,0 则禁用事件
private final long allldleTimeNanos;//读或写空闲时间,0 则禁用事件
handlerAdded 方法
当该 hander 被添加到 pipeline 中时,则调用 initialize 方法
private void initialize(ChannelHandlerContext ctx)f
// Avoid the case where destroy()is called before scheduling timeouts// See: https://github.com/netty/netty/issues/143
switch(state)f
case 1:
case 2.
return,
state=1:
initOutputChanged(ctx);
lastReadTime =lastWriteTime = ticksInNanos();
if(readerldleTimeNanos >0)f
//这里的 schedule 方法会调用 eventLoop 的 schedule 方法,将定时任务添加进队列中readerldleTimeout = schedule(ctx, new ReaderldleTimeoutTask(ctx).
readerldleTimeNanos, TimeUnit.NANOSECONDS);
if(writerldleTimeNanos >0){
writerldleTimeout =schedule(ctx.new WriterldleTimeoutTask(ctx)writerldleTimeNanos.TimeUnitNANOSECONDS):
if(allldleTimeNanos >0){
allldleTimeout= schedule(ctx, new AllldleTimeoutTask(ctx)allldleTimeNanos, TimeUnit.NANOSECONDS);
只要给定的参数大于 0,就创建一个定时任务,每个事件都创建。同时,将 state 状态设置为 1,防止重复初始化.。调用 initOutputChanged 方法,初始化 “监控出站数据属性”