netty发送心跳测试

heartbeat test

intro

多个微服务之间,需要通过心跳来判断服务到底还是不是活着。

netty可以轻松地完成心跳连接的逻辑。

这时我们要介绍一个handler:IdleStateHandler

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

如果一个channel没有读或者没有写或者两者都没有,就会触发一个IdleStateEvent

IdleStateEvent这个类中,有一个保存空闲状态的属性:

    private final IdleState state;

空闲状态一共有三种:

/**
 * An {@link Enum} that represents the idle state of a {@link Channel}.
 */
public enum IdleState {
    /**
     * No data was received for a while.
     */
    READER_IDLE,
    /**
     * No data was sent for a while.
     */
    WRITER_IDLE,
    /**
     * No data was either received or sent for a while.
     */
    ALL_IDLE
}

server

服务端还是模板代码:

public class TestHeartBeatServer {
    public static void main(String[] args) throws  Exception{

        EventLoopGroup bossGroup=new NioEventLoopGroup();
        EventLoopGroup workerGroup=new NioEventLoopGroup();
        try{
            ServerBootstrap serverBootstrap=new ServerBootstrap();

            serverBootstrap.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class).
                    handler(new LoggingHandler(LogLevel.INFO)).
                    childHandler(new TestHeartBeatServerInitializer());
            ChannelFuture channelFuture=serverBootstrap.bind(8899).sync();
            channelFuture.channel().closeFuture().sync();
        }finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

初始化器:

public class TestHeartBeatServerInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
            ChannelPipeline pipeline = ch.pipeline();

            pipeline.addLast(new IdleStateHandler(5,7,0, TimeUnit.SECONDS));

            pipeline.addLast(new TestHeartBeatServerHandler());
        }

    }
new IdleStateHandler(5,7,0, TimeUnit.SECONDS)

5表示如果客户端5秒内没有发送消息,就会触发读超时事件;

7表示如果服务端7秒内没有向客户端发送消息,就会触发写超时事件;

0表示暂时不要读写超时。


我们将自定义handler将以上的信息打印出来:

public class TestHeartBeatServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            String eventType = null;
            switch (event.state()) {
                case READER_IDLE:
                    eventType = "read idle";
                    break;
                case WRITER_IDLE:
                    eventType = "write idle";
                    break;
                case ALL_IDLE:
                    eventType = "read write idle";
                    break;
            }
            System.out.println(ctx.channel().remoteAddress() + "---idle event :" + eventType);
            ctx.channel().close();
        }
    }
}


test

启动server。

使用telnet连接:

5秒钟什么都不输入,服务端就会给出读超时异常:

再连一次,如果客户端不断输入东西:

此时不会有读超时。

服务端7秒内没有写出东西(我们没有写这个逻辑),所以7秒后就会:

现在我们要触发读写超时:

new IdleStateHandler(5,7,0, TimeUnit.SECONDS)

0改成3

意思是,3秒内如果客户端没输入东西,服务端也没发东西,就会触发读写超时事件。

测试是成功的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章