kafka-client 优雅关停

以下给出一个参考示例,但具体的某些细节的处理还需要根据自己的业务自行抉择

实现思路,通过 consumer.wakeup() 方法让  poll 方法抛出异常,然后捕获异常,退出

《kafka权威指南》 第 64 页也有给出示例,有兴趣的可以找来看看

// 消费线程

private Thread consumerThread;

// 线程名称,自己设置下

private String threadName;

private volatile boolean running = false;

// 业务线程池,请根据自己的业务设置合理参数

private ExecutorService pool = new ThreadPoolExecutor(

    Runtime.getRuntime().availableProcessors() * 2,

    Runtime.getRuntime().availableProcessors() * 2120, TimeUnit.SECONDS,

    blockingDeque, NamedThreadFactory.create(THREAD_POOL_NAME_PREFIX + threadName + "-"),

    new CallerRunsPolicy()

);;

public synchronized void start() {

  // 此处省略 consumer 初始化的过程

  consumer = null;

  consumer.subscribe(Lists.newArrayList("topic-aaa"));

  running = true;

  consumerThread = new Thread(() -> {

    while (running) {

      try {

        ConsumerRecords<String, String> records = consumer.poll(500);

        for (ConsumerRecord<String, String> record : records) {

          // 放入自己的业务线程池

          pool.submit(new Worker(record, records));

        }

      catch (WakeupException exception) {

        // 捕获 WakeupException consumer 准备退出

        LOG.info("WakeupException 准备关闭consumer");

        // 跳出循环,关闭consumer

        break;

      catch (Exception exception) {

        LOG.error("error cause by ", exception);

      }

    }

    consumer.close();

    // 此处使用的 guava 的线程池关闭方法,也可以根据自己的需求去自定义实现线程池关闭逻辑,阻塞时间请根据业务情况自行设置

    boolean isTerminated = MoreExecutors.shutdownAndAwaitTermination(pool, 1, TimeUnit.SECONDS);

    LOG.info("consumer closed ,poll terminated:{}", isTerminated);

  });

  consumerThread.setName(threadName);

  consumerThread.start();

}

public synchronized void close() {

  if (!running) {

    LOG.info("consumer 不是运行状态,不需要关闭,threadName[{}]", threadName);

    return;

  }

  Stopwatch stopwatch = Stopwatch.createStarted();

  running = false;

  consumer.wakeup();

  try {

    // 等待counsumer线程执行完成

    consumerThread.join();

  catch (InterruptedException e) {

    LOG.error("consumerThread.join InterruptedException", e);

  }

  LOG.info("consumer线程关闭完成,threadName[{}],Spend time[{}]", threadName, stopwatch);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tudou186

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值