[Java大数据入门]Kafka编程示例-Producer

Kafka0.9版本以后关于producer和consumer的实现跟0.8版本相比有了很大的不同,目前网上关于新版的生产者和消费者的示例代码很少,因此想要实现在生产中可以使用的producer和consumer代码。本文会主要实现producer相关的代码,下一篇文章会实现多线程的consumer代码

在阅读本文之前,强烈建议先阅读以下一篇博文,将新版kafka producer的原理讲解的很透彻:Kafka producer介绍

大家在了解了producer的基本原理之后,我们来看下代码的具体实现:源代码地址

一、引入pom依赖

<dependency>
    <groupId>org.apache.kafkagroupId>
    <artifactId>kafka_2.12artifactId>
    <version>1.0.0version>
    <exclusions>
        <exclusion>
            <groupId>org.apache.zookeepergroupId>
            <artifactId>zookeeperartifactId>
        exclusion>
        <exclusion>
            <groupId>org.slf4jgroupId>
            <artifactId>slf4j-log4j12artifactId>
        exclusion>
        <exclusion>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
        exclusion>
    exclusions>
dependency>

这个pom会在你的项目工程中引入两个jar包:

  • org.apache.kafka:kafka-clients:1.0.0

  • org.apache.kafka:kafka_2.12:1.0.0

由于在我的项目中有单独的zk和日志jar包,所以在引入kafka的时候需要将相关的包排除掉

二、编写示例代码

代码如下

package com.russell.bigdata.kafka.handler;

import org.apache.kafka.clients.producer.Callback;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.serialization.StringSerializer;

import java.util.Properties;

/**
 * kafka 1.0版本的生产者 handler
 *
 * @author liumenghao
 * @Date 2019/1/13
 */
public class ProducerHandler10 {

    /**
     * 序列化方法
     */
    private static final String DEFAULT_SERIALIZER_CLASS = StringSerializer.class.getName();

    /**
     * kafka api中的生产者
     */
    private KafkaProducer kafkaProducer;

    /**
     * kafka生产者构造方法
     *
     * @param brokerList kafka节点信息
     */
    public ProducerHandler10(String brokerList) {

        Properties producerConfig = createProducerConfig(brokerList, DEFAULT_SERIALIZER_CLASS);

        kafkaProducer = new KafkaProducer(producerConfig);
    }

    /**
     * 发送消息到kafka
     *
     * @param topic 消息被发送到的topic
     * @param value 发送的消息的内容
     */
    public void sendMessage(String topic, String value) {
        ProducerRecord data = new ProducerRecord(topic, value);
        kafkaProducer.send(data);
    }

    /**
     * 发送消息到kafka,可以使用回调函数对发送结果进行处理
     *
     * @param topic
     * @param value
     * @param callback
     */
    public void sendMessage(String topic, String value, Callback callback) {
        ProducerRecord data = new ProducerRecord(topic, value);
        kafkaProducer.send(data, callback);
    }

    /**
     * 关闭kafka,释放资源
     */
    public void close() {
        kafkaProducer.close();
    }

    /**
     * 创建kafka配置类
     *
     * @param brokerList
     * @param serializerClass
     * @return
     */
    private Properties createProducerConfig(String brokerList, String serializerClass) {
        Properties props = new Properties();
        // broker 列表
        props.put("bootstrap.servers", brokerList);
        // 设置对key序列化的类
        props.put("key.serializer", serializerClass);
        // 设置对value序列化的类
        props.put("value.serializer", serializerClass);

        /**
         * 0        不等待结果返回
         * 1        等待至少有一个服务器返回数据接收标识
         * -1或all  表示必须接受到所有的服务器返回标识,及同步写入
         */
        props.put("request.required.acks", "1");

        /**
         * 内部发送数据是异步还是同步
         * sync 同步,默认
         * async异步
         */
        props.put("producer.type", "async");
        return props;
    }
}

这个类就是在Kafka Api中的KafkaProducer类上封装了一层

关键的几个类

1、org.apache.kafka.clients.producer.KafkaProducer

生产者的构造方法类,用来进行消息的发送操作

2、org.apache.kafka.clients.producer.ProducerRecord

发送到kafka的数据的模型抽象

其中sendMessage,有两个方法。其中一个添加了回调函数Callback,可以对服务端接收到消息后返回的信息RecordMetadata进行业务相关的处理。下面我们通过测试方法来看Producer Handler的使用

三、代码测试

package com.russell.bigdata.kafka.example;

import com.russell.bigdata.kafka.common.KafkaTopicType;
import com.russell.bigdata.kafka.handler.ProducerHandler10;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.producer.RecordMetadata;

import static com.russell.bigdata.kafka.common.Constants.KAFKA_BROKER;

/**
 * 测试使用,感受kafka java producer api的使用方式
 *
 * @author liumenghao
 * @Date 2019/2/22
 */
@Slf4j
@Data
public class ProducerTest {

    private static int count;

    public static void main(String[] args) throws Exception {
        ProducerHandler10 producer = new ProducerHandler10(KAFKA_BROKER);
        while (true) {
            Thread.sleep(1000);
            String topic = KafkaTopicType.THREE_PARTITION_TOPIC.getName();
            String message = "测试生产数据 " + count;
            producer.sendMessage(topic, message,
                    (metadata, exception) -> callback(metadata, exception));
            log.info("测试生产数据" + " " + count);
            count++;
        }
    }

    /**
     * 回调函数,当kafka发送数据完成后,会从服务端返回一个RecordMetadata
     *
     * @param metadata
     * @param exception
     */
    private static void callback(RecordMetadata metadata, Exception exception) {
        String topic = metadata.topic();
        Integer partition = metadata.partition();
        Long offset = metadata.offset();
        log.info("topic={}, partition={}, offset={}", topic, partition, offset);
    }
}

直接使用带有KafkaCallback参数的sendMessage重载方法进行测试,当数据发到到服务端成功后,将数据写入的topic,partition以及offset的信息打印出来。最终的测试结果如下:

测试生产数据 0
topic=kafka_partitions_topic, partition=2, offset=382
测试生产数据 1
topic=kafka_partitions_topic, partition=1, offset=383
测试生产数据 2
topic=kafka_partitions_topic, partition=0, offset=382
测试生产数据 3
topic=kafka_partitions_topic, partition=2, offset=383

四、总结

本文只是从代码层面讲解了1.0.0版本的Kafka Producer的实现,对其中的一些具体的类,例如KafkaProducer、ProducerRecord等没有深入讲解,因为我个人一直秉持的一个理念是,最好的学习方式就是直接读源码。示例代码相当于是给了你一个入门的概念,然后顺着这个demo去深入。

你可能感兴趣的:(Java大数据入门)