Netty 客户端使用指数退避机制实现重连

指数退避

可以理解为每次重连失败时,就把重连时间设置为之前的指数级别。例如 2 秒,4 秒,8 秒......

亚马逊AWS关于指数退避的两篇文章介绍

Netty客户端中使用指数退避方式重连

客户端连接服务器时,调用 Bootstrap 的 connect 方法:

bootstrap.connect(host, port)

这个方法会返回 ChannelFuture ,ChannelFuture 实现了 netty 的 Future , 而Future 继承自 java.util.concurrent.Future ,这是异步操作的结果,因此 connect 方法是一个异步方法。我们可以通过调用addListener 添加监听器,监听是否连接成功。

  • 这里使用 GenericFutureListener ,也可以使用 ChannelFutureListener 这个接口。
   /**
     * 连接和重连机制,实现了指数退避重连
     * @param bootstrap
     * @param host
     * @param port
     * @param retry
     */
    private static void connect(Bootstrap bootstrap, String host, int port, int retry) {

        bootstrap.connect(host, port).addListener(new GenericFutureListener<Future<? super Void>>() {
            @Override
            public void operationComplete(Future<? super Void> future) throws Exception {
                if (future.isSuccess()) {
                    LOGGER.info("连接服务器成功!");
                } else if (retry == 0) {
                    LOGGER.error("重连次数已用完,放弃连接!");
                } else {
                    // 第几次重连
                    int order = (MAX_RETRY - retry) + 1;
                    // 本次重连的间隔
                    int delay = 1 << order;
                    LOGGER.error(new Date() + ": 连接失败,第" + order + "次重连……");

                    bootstrap.config().group().schedule(() -> connect(bootstrap, host, port, retry - 1), delay, TimeUnit.SECONDS);
                }
            }
        });
    }
  • 通过future.isSuccess() 判断是否连接成功。
  • int delay = 1 << order; 通过左移操作快速计算出重连时间间隔。
  • bootstrap.config().group().schedule() 实现定时任务逻辑。

参考

美团闪电侠客户端启动流程

posted @ 2019-07-28 22:03  monkjavaer  阅读(691)  评论(0编辑  收藏  举报