三、kafka生产者客户端

(一)添加依赖
  记住,java客户端的版本号一定要和Kafka集群的版本号一致!!!

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

(二)实际操作


import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import java.util.Properties;
import java.util.concurrent.ExecutionException;

/**
 * @author 咸鱼
 * @date 2018/8/27 20:11
 */
public class ProducerDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        /**
         * 属性说明;
         * bootstrap.servers:host/port列表,用于初始化建立和Kafka集群的连接。列表格式为host1:port1,
         *                    host2:port2,....,无需添加所有的集群地址,kafka会根据提供的地址发现其
         *                    他的地址(你可以多提供几个,以防提供的服务器关闭)。
         *
         * acks:生产者需要leader确认请求完成之前接收的应答数。此配置控制了发送消息的耐用性,支持以下配置:
                 acks=0 如果设置为0,那么生产者将不等待任何消息确认。消息将立刻天际到socket缓冲区并考虑发送。
                        在这种情况下不能保障消息被服务器接收到。并且重试机制不会生效(因为客户端不知道故障了
                        没有)。每个消息返回的offset始终设置为-1。
                 acks=1,这意味着leader写入消息到本地日志就立即响应,而不等待所有follower应答。在这种情况下,
                         如果响应消息之后但follower还未复制之前leader立即故障,那么消息将会丢失。
                 acks=all 这意味着leader将等待所有副本同步后应答消息。此配置保障消息不会丢失(只要至少有一个
                          同步的副本或者)。这是最强壮的可用性保障。等价于acks=-1。
         *
         * retries:设置一个比零大的值,客户端如果发送失败则会重新发送。注意,这个重试功能和客户端在接到错误
         *          之后重新发送没什么不同。如果max.in.flight.requests.per.connection没有设置为1,有可能改变
         *          消息发送的顺序,因为如果2个批次发送到一个分区中,并第一个失败了并重试,但是第二个成功了,
         *          那么第二个批次将超过第一个。注:如果启用重试,则会有重复消息的可能性。
         *
         * batch.size:当多个消息要发送到相同分区的时,生产者尝试将消息批量打包在一起,以减少请求交互。这样有
         *             助于客户端和服务端的性能提升。该配置的默认批次大小(以字节为单位):不会打包大于此配置
         *             大小的消息。发送到broker的请求将包含多个批次,每个分区一个,用于发送数据。较小的批次大
         *             小有可能降低吞吐量(批次大小为0则完全禁用批处理)。一个非常大的批次大小可能更浪费内存。
         *             因为我们会预先分配这个资源。
         *
         * linger.ms:生产者组将发送的消息组合成单个批量请求。正常情况下,只有消息到达的速度比发送速度快的情
         *            况下才会出现。但是,在某些情况下,即使在适度的负载下,客户端也可能希望减少请求数量。此
         *            设置通过添加少量人为延迟来实现。- 也就是说,不是立即发出一个消息,生产者将等待一个给定
         *            的延迟,以便和其他的消息可以组合成一个批次。这类似于Nagle在TCP中的算法。此设置给出批量
         *            延迟的上限:一旦我们达到分区的batch.size值的记录,将立即发送,不管这个设置如何,但是,
         *            如果比这个小,我们将在指定的“linger”时间内等待更多的消息加入。此设置默认为0(即无延迟)。
         *            假设,设置 linger.ms=5,将达到减少发送的请求数量的效果,但对于在没有负载情况,将增加5ms的
         *            延迟。
         *
         * buffer.memory:生产者用来缓存等待发送到服务器的消息的内存总字节数。如果消息发送速度比其传输到服务
         *                器的快,将会耗尽这个缓存空间。当缓存空间耗尽,其他发送调用将被阻塞,阻塞时间的阈值
         *                通过max.block.ms设定,之后它将抛出一个TimeoutException。
         *
         * key.serializer、value.serializer:将用户提供的key和value对象ProducerRecord转换成字节,你可以使用附
         *                                   带的ByteArraySerializaer或StringSerializer处理简单的string或byte类型。
         */
        Properties properties = new Properties();
        properties.put("bootstrap.servers", "192.168.10.130:9092");
        properties.put("acks", "all");
        properties.put("retries", 0);
        properties.put("batch.size", 16340);
        properties.put("linger.ms", 1);
        properties.put("buffer.memory", 33554432);
        properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        properties.put("request.timeout.ms", "10000");

        Producer<String, String> producer = new KafkaProducer<String, String>(properties);

        /**
         * public Future<RecordMetadata> send(ProducerRecord<K,V> record,Callback callback)
         *    异步发送一条消息到topic,并调用callback(当发送已确认)。
         *    send是异步的,并且一旦消息被保存在等待发送的消息缓存中,此方法就立即返回。这样并行发送多
         *条消息而不阻塞去等待每一条消息的响应。
         *    发送的结果是一个RecordMetadata,它指定了消息发送的分区,分配的offset和消息的时间戳。如果
         *topic使用的是CreateTime,则使用用户提供的时间戳或发送的时间(如果用户没有指定指定消息的时间戳)
         *如果topic使用的是LogAppendTime,则追加消息时,时间戳是broker的本地时间。
         *    由于send调用是异步的,它将为分配消息的此消息的RecordMetadata返回一个Future。如果future调用
         *get(),则将阻塞,直到相关请求完成并返回该消息的metadata,或抛出发送异常。
         */
        for (int i=0; i<100; i++){
            producer.send(new ProducerRecord<String, String>("my-replicated-topic", Integer.toString(i), Integer.toString(i)));
            if(i==99){
                System.out.println("------------------------------------------");
            }
        }
        producer.close();
    }
}

(三)可能出现的问题
  TimeoutException:如果版本一致,且程序未错,那就是集群里面有端口未开!!!!!!!

猜你喜欢

转载自blog.csdn.net/panchang199266/article/details/82120368
今日推荐