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秒內如果客戶端沒輸入東西,服務端也沒發東西,就會觸發讀寫超時事件。

測試是成功的。

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