Java实现Kafka生产者和消费者的示例

简介: Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写。Kafka的目标是为处理实时数据提供一个统一、高吞吐、低延迟的平台。

Kafka简介

Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写。Kafka的目标是为处理实时数据提供一个统一、高吞吐、低延迟的平台。

方式一:kafka-clients

引入依赖

在pom.xml文件中,引入kafka-clients依赖:

<dependency>
    <groupId>org.apache.kafka</groupId>
    <artifactId>kafka-clients</artifactId>
    <version>2.3.1</version>
</dependency>

生产者

创建一个KafkaProducer的生产者实例:

@Configuration
public class Config {

    public final static String bootstrapServers = "127.0.0.1:9092";

    @Bean(destroyMethod = "close")
    public KafkaProducer<String, String> kafkaProducer() {
        Properties props = new Properties();
        //设置Kafka服务器地址
        props.put("bootstrap.servers", bootstrapServers);
        //设置数据key的序列化处理类
        props.put("key.serializer", StringSerializer.class.getName());
        //设置数据value的序列化处理类
        props.put("value.serializer", StringSerializer.class.getName());
        KafkaProducer<String, String> producer = new KafkaProducer<>(props);
        return producer;
    }
}

在Controller中进行使用:

@RestController
@Slf4j
public class Controller {

    @Autowired
    private KafkaProducer<String, String> kafkaProducer;

    @RequestMapping("/kafkaClientsSend")
    public String send() {
        String uuid = UUID.randomUUID().toString();
        RecordMetadata recordMetadata = null;
        try {
            //将消息发送到Kafka服务器的名称为“one-more-topic”的Topic中
            recordMetadata = kafkaProducer.send(new ProducerRecord<>("one-more-topic", uuid)).get();
            log.info("recordMetadata: {}", recordMetadata);
            log.info("uuid: {}", uuid);
        } catch (Exception e) {
            log.error("send fail, uuid: {}", uuid, e);
        }
        return uuid;
    }
}

消费者

创建一个KafkaConsumer的消费者实例:

@Configuration
public class Config {

    public final static String groupId = "kafka-clients-group";
    public final static String bootstrapServers = "127.0.0.1:9092";

    @Bean(destroyMethod = "close")
    public KafkaConsumer<String, String> kafkaConsumer() {
        Properties props = new Properties();
        //设置Kafka服务器地址
        props.put("bootstrap.servers", bootstrapServers);
        //设置消费组
        props.put("group.id", groupId);
        //设置数据key的反序列化处理类
        props.put("key.deserializer", StringDeserializer.class.getName());
        //设置数据value的反序列化处理类
        props.put("value.deserializer", StringDeserializer.class.getName());
        props.put("enable.auto.commit", "true");
        props.put("auto.commit.interval.ms", "1000");
        props.put("session.timeout.ms", "30000");
        KafkaConsumer<String, String> kafkaConsumer = new KafkaConsumer<>(props);
        //订阅名称为“one-more-topic”的Topic的消息
        kafkaConsumer.subscribe(Arrays.asList("one-more-topic"));
        return kafkaConsumer;
    }
}

在Controller中进行使用:

@RestController
@Slf4j
public class Controller {

    @Autowired
    private KafkaConsumer<String, String> kafkaConsumer;

    @RequestMapping("/receive")
    public List<String> receive() {
        ////从Kafka服务器中的名称为“one-more-topic”的Topic中消费消息
        ConsumerRecords<String, String> records = kafkaConsumer.poll(Duration.ofSeconds(1));
        List<String> messages = new ArrayList<>(records.count());
        for (ConsumerRecord<String, String> record : records.records("one-more-topic")) {
            String message = record.value();
            log.info("message: {}", message);
            messages.add(message);
        }
        return messages;
    }
}

方式二:spring-kafka

使用kafka-clients需要我们自己创建生产者或者消费者的bean,如果我们的项目基于SpringBoot构建,那么使用spring-kafka就方便多了。

引入依赖

在pom.xml文件中,引入spring-kafka依赖:

<dependency>
    <groupId>org.springframework.kafka</groupId>
    <artifactId>spring-kafka</artifactId>
    <version>2.3.12.RELEASE</version>
</dependency>

生产者

在application.yml文件中增加配置:

spring:
  kafka:
      #Kafka服务器地址
    bootstrap-servers: 127.0.0.1:9092
    producer:
      #设置数据value的序列化处理类
      value-serializer: org.apache.kafka.common.serialization.StringSerializer

在Controller中注入KafkaTemplate就可以直接使用了,代码如下:

@RestController
@Slf4j
public class Controller {

    @Autowired
    private KafkaTemplate<String, String> template;

    @RequestMapping("/springKafkaSend")
    public String send() {
        String uuid = UUID.randomUUID().toString();
        //将消息发送到Kafka服务器的名称为“one-more-topic”的Topic中
        this.template.send("one-more-topic", uuid);
        log.info("uuid: {}", uuid);
        return uuid;
    }
}

消费者

在application.yml文件中增加配置:

spring:
  kafka:
    #Kafka服务器地址
    bootstrap-servers: 127.0.0.1:9092
    consumer:
      #设置数据value的反序列化处理类
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer

创建一个可以被Spring框架扫描到的类,并且在方法上加上@KafkaListener注解,就可以消费消息了,代码如下:

@Component
@Slf4j
public class Receiver {

    @KafkaListener(topics = "one-more-topic", groupId = "spring-kafka-group")
    public void listen(ConsumerRecord<?, ?> record) {
        Optional<?> kafkaMessage = Optional.ofNullable(record.value());
        if (kafkaMessage.isPresent()) {
            String message = (String) kafkaMessage.get();
            log.info("message: {}", message);
        }
    }
}
相关文章
|
1月前
|
Java
在 Java 中捕获和处理自定义异常的代码示例
本文提供了一个 Java 代码示例,展示了如何捕获和处理自定义异常。通过创建自定义异常类并使用 try-catch 语句,可以更灵活地处理程序中的错误情况。
68 1
|
2月前
|
存储 Java
Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。
【10月更文挑战第19天】本文详细介绍了Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。HashMap以其高效的插入、查找和删除操作著称,而TreeMap则擅长于保持元素的自然排序或自定义排序,两者各具优势,适用于不同的开发场景。
53 1
|
4天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者
|
1月前
|
Java
在Java中实现接口的具体代码示例
可以根据具体的需求,创建更多的类来实现这个接口,以满足不同形状的计算需求。希望这个示例对你理解在 Java 中如何实现接口有所帮助。
87 38
|
1月前
|
消息中间件 缓存 Java
java nio,netty,kafka 中经常提到“零拷贝”到底是什么?
零拷贝技术 Zero-Copy 是指计算机执行操作时,可以直接从源(如文件或网络套接字)将数据传输到目标缓冲区, 而不需要 CPU 先将数据从某处内存复制到另一个特定区域,从而减少上下文切换以及 CPU 的拷贝时间。
java nio,netty,kafka 中经常提到“零拷贝”到底是什么?
|
2月前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
92 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
2月前
|
安全 Java
Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧
【10月更文挑战第20天】Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧,包括避免在循环外调用wait()、优先使用notifyAll()、确保线程安全及处理InterruptedException等,帮助读者更好地掌握这些方法的应用。
25 1
|
2月前
|
Java
让星星⭐月亮告诉你,jdk1.8 Java函数式编程示例:Lambda函数/方法引用/4种内建函数式接口(功能性-/消费型/供给型/断言型)
本示例展示了Java中函数式接口的使用,包括自定义和内置的函数式接口。通过方法引用,实现对字符串操作如转换大写、数值转换等,并演示了Function、Consumer、Supplier及Predicate四种主要内置函数式接口的应用。
32 1
|
消息中间件 存储 缓存
Kafka 3.0重磅发布,弃用 Java 8 的支持!
Kafka 3.0重磅发布,弃用 Java 8 的支持!
1178 0
Kafka 3.0重磅发布,弃用 Java 8 的支持!
|
6天前
|
安全 Java Kotlin
Java多线程——synchronized、volatile 保障可见性
Java多线程中,`synchronized` 和 `volatile` 关键字用于保障可见性。`synchronized` 保证原子性、可见性和有序性,通过锁机制确保线程安全;`volatile` 仅保证可见性和有序性,不保证原子性。代码示例展示了如何使用 `synchronized` 和 `volatile` 解决主线程无法感知子线程修改共享变量的问题。总结:`volatile` 确保不同线程对共享变量操作的可见性,使一个线程修改后,其他线程能立即看到最新值。