java 多线程消费kfk队列消息案例

简介: 很久之前老师写的,记录一下,不然找不到了

package org.training.hadoop.kafka;

import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.common.errors.WakeupException;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

public class KafkaConsumerExample
{

//config
public static Properties getConfig()
{
    Properties props = new Properties();
    props.put("bootstrap.servers", "localhost:9092");
    props.put("group.id", "testGroup");
    props.put("enable.auto.commit", "true");
    props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
    props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");

    return props;
}

public void consumeMessage()
{
    // launch 3 threads to consume
    int numConsumers = 3;
    final String topic = "test1";
    final ExecutorService executor = Executors.newFixedThreadPool(numConsumers); //创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待
    final List<KafkaConsumerRunner> consumers = new ArrayList<KafkaConsumerRunner>();
    for (int i = 0; i < numConsumers; i++) {
        KafkaConsumerRunner consumer = new KafkaConsumerRunner(topic);
        consumers.add(consumer);
        executor.submit(consumer);
    }

    //关闭线程并清理---------------------------
    //当jvm关闭的时候,会执行系统中已经设置的所有通过方法addShutdownHook添加的钩子,清理
    Runtime.getRuntime().addShutdownHook(new Thread()
    {
        @Override
        public void run()
        {
            for (KafkaConsumerRunner consumer : consumers) {
                consumer.shutdown();  //关闭线程
            }
            executor.shutdown();
            try {
                //当前线程阻塞,直到
                //等所有已提交的任务(包括正在跑的和队列中等待的)执行完或者等超时时间到
                //或者线程被中断,抛出InterruptedExcepti
                executor.awaitTermination(5000, TimeUnit.MILLISECONDS);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });
}

// Thread to consume kafka data
public static class KafkaConsumerRunner
        implements Runnable
{
    private final AtomicBoolean closed = new AtomicBoolean(false);
    private final KafkaConsumer<String, String> consumer;
    private final String topic;

    public KafkaConsumerRunner(String topic)
    {
        Properties props = getConfig();
        consumer = new KafkaConsumer<String, String>(props);
        this.topic = topic;
    }

    public void handleRecord(ConsumerRecord record)
    {
        System.out.println("name: " + Thread.currentThread().getName() + " ; topic: " + record.topic() + " ; offset" + record.offset() + " ; key: " + record.key() + " ; value: " + record.value());
    }

    public void run()
    {
        try {
            // subscribe
            consumer.subscribe(Arrays.asList(topic));
            while (!closed.get()) {
                //read data
                ConsumerRecords<String, String> records = consumer.poll(10000); //poll方法消费数据,心跳机制通知broker是否正常
                // Handle new records
                for (ConsumerRecord<String, String> record : records) {
                    handleRecord(record);  //打印消费数据
                }
            }
        }
        catch (WakeupException e) {
            // Ignore exception if closing
            if (!closed.get()) {
                throw e;
            }
        }
        finally {
            consumer.close();
        }
    }

    // Shutdown hook which can be called from a separate thread
    public void shutdown()
    {
        closed.set(true);
        consumer.wakeup();
    }
}

public static void main(String[] args)
{
    KafkaConsumerExample example = new KafkaConsumerExample();
    example.consumeMessage();
}

}

相关文章
|
1天前
|
消息中间件 缓存 NoSQL
Java多线程实战-CompletableFuture异步编程优化查询接口响应速度
Java多线程实战-CompletableFuture异步编程优化查询接口响应速度
|
1天前
|
数据采集 存储 Java
高德地图爬虫实践:Java多线程并发处理策略
高德地图爬虫实践:Java多线程并发处理策略
|
2天前
|
缓存 Java
【Java基础】简说多线程(上)
【Java基础】简说多线程(上)
6 0
|
2天前
|
SQL Dubbo Java
案例分析|线程池相关故障梳理&总结
本文作者梳理和分享了线程池类的故障,分别从故障视角和技术视角两个角度来分析总结,故障视角可以看到现象和教训,而技术视角可以透过现象看到本质更进一步可以看看如何避免。
|
2天前
|
并行计算 算法 安全
Java从入门到精通:2.1.3深入学习Java核心技术——掌握Java多线程编程
Java从入门到精通:2.1.3深入学习Java核心技术——掌握Java多线程编程
|
2天前
|
安全 Java 编译器
是时候来唠一唠synchronized关键字了,Java多线程的必问考点!
本文简要介绍了Java中的`synchronized`关键字,它是用于保证多线程环境下的同步,解决原子性、可见性和顺序性问题。从JDK1.6开始,synchronized进行了优化,性能得到提升,现在仍可在项目中使用。synchronized有三种用法:修饰实例方法、静态方法和代码块。文章还讨论了synchronized修饰代码块的锁对象、静态与非静态方法调用的互斥性,以及构造方法不能被同步修饰。此外,通过反汇编展示了`synchronized`在方法和代码块上的底层实现,涉及ObjectMonitor和monitorenter/monitorexit指令。
15 0
|
2天前
|
监控 安全 Java
在Java中如何优雅的停止一个线程?可别再用Thread.stop()了!
在Java中如何优雅的停止一个线程?可别再用Thread.stop()了!
10 2
|
2天前
|
Java 调度
Java面试必考题之线程的生命周期,结合源码,透彻讲解!
Java面试必考题之线程的生命周期,结合源码,透彻讲解!
28 1
|
存储 算法 安全
【Java 数据结构及算法实战】系列 014:Java队列08——数组实现的双端队列ArrayDeque
【Java 数据结构及算法实战】系列 014:Java队列08——数组实现的双端队列ArrayDeque
138 0
【Java 数据结构及算法实战】系列 014:Java队列08——数组实现的双端队列ArrayDeque
|
存储 算法 安全
【Java数据结构及算法实战】系列012:Java队列06——数组实现的优先级阻塞队列PriorityBlockingQueue
【Java数据结构及算法实战】系列012:Java队列06——数组实现的优先级阻塞队列PriorityBlockingQueue
117 0

热门文章

最新文章