netty斷線重連


一 什么是斷線重連

斷線重連是指由於發生網絡故障而導致服務中斷的情況,客戶端就需要從重新連接服務端;哪些情況下會導致服務斷線呢?常見 的就是 網絡情況下,斷斷續續,導致客戶端無法和服務端交互,再比如,機房斷電也會導致服務宕機;所以在netty中對服務進行斷線重連是非常有必要的做的一個流程;

二 netty斷線重連步驟

netty 什么情況下需要斷線重連?

netty 剛剛啟動時需要斷線重連,有可能服務剛剛啟動,連接失敗,此時就可以嘗試斷線重連,保證服務正常運行;其次,當服務在運行過程中出現網絡故障的時候需要斷線重連,這樣能保證服務即使宕機恢復后也能馬上恢復;所以 netty 的斷線重連需要 2 步驟,缺一不可;

三 客戶端斷線重連

netty 的服務端一般情況下不需要斷線重連,應為服務端服務宕機就只能重新啟動服務;所以今天我們研究的是客戶端的斷線重連;

3.1 服務啟動時斷線重連

首先 我們需要寫一個監聽器 實現 ChannelFutureListener 接口的 operationComplete 方法, 在這邊 我們 使用構造器注入的方式獲取 nettyClient 實例, 當客戶端連接操作完成后啟動一個負載監聽,在方法中我們使用 channelFuture.isSuccess() 的 結果進行判定 客戶端的連接是否啟動成功;如果沒有啟動成功則啟動新的線程進行重連,確保客戶端連接時能連接成功;

@Slf4j
public class ConnectionListener implements ChannelFutureListener {
    private NettyClient nettyClient;
    public ConnectionListener(NettyClient nettyClient) {
        this.nettyClient = nettyClient;
    }
    @Override
    public void operationComplete(ChannelFuture channelFuture) throws Exception {
        if (!channelFuture.isSuccess()) {
            log.warn("-------------客戶端重新連接-----------------");
            final EventLoop loop = channelFuture.channel().eventLoop();
            loop.schedule(new Runnable() {
                @SneakyThrows
                @Override
                public void run() {
                    nettyClient.connect(8080,"127.0.0.1");
                }
            }, 1L, TimeUnit.SECONDS);
        }
    }

}

這邊我們只是實現了一個監聽器,我們還需要把監聽器注入到客戶端;

public void connect(int port, String host) {

        // 創建線程組
        NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup();
        // netty啟動輔助類
        Bootstrap bootstrap = new Bootstrap();
        //
        bootstrap.group(nioEventLoopGroup)
                .channel(NioSocketChannel.class)
                .option(ChannelOption.TCP_NODELAY, true)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        // 處理IO事件
                        ChannelPipeline pipeline = socketChannel.pipeline();
                        // 異常斷線重連
                        pipeline.addLast(new NettyClientHandler(new NettyClient()));
                    }
                });
        // 異步操作
        ChannelFuture connect = null;
        try {
            connect = bootstrap
                    .connect(host, port)
                    .addListener(new ConnectionListener(this))// netty 啟動時如果連接失敗,會斷線重連
                    .sync();
            // 關閉客戶端
            connect.channel()
                    .closeFuture()
                    .sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

3.2 服務運行中斷重連

我們 在 NettyClientHandler 實現一個 channelInactive 方法,當服務端斷線時 我們會觸發這個方法重啟啟動一個線程進行斷線重連;

@Slf4j
public class NettyClientHandler extends ChannelInboundHandlerAdapter {

    private NettyClient nettyClient;


    public NettyClientHandler(NettyClient nettyClient) {
        this.nettyClient = nettyClient;
    }
	// ....

    /**
     * @Author lsc
     * <p> 運行時斷線重連</p>
     * @Param [ctx]
     * @Return
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        final EventLoop eventLoop = ctx.channel().eventLoop();
        eventLoop.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("22222222222222222");
                nettyClient.connect(8080, "127.0.0.1");
            }
        }, 1L, TimeUnit.SECONDS);
        super.channelInactive(ctx);
    }
	// ....
}

四 模擬斷線重連

首先我們先啟動 服務端和 客戶端,知識追尋者 的代碼有個應答 消息;

服務端圖片效果如下

客戶端圖片效果如下

將 服務端 停止 ,客戶端會進行斷線重連

圖片效果如下

重新啟動服務端,重連成功

本套教程


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM