1,producer 工作流程:
producer 的功能就是向某个 topic 的某个分区发送一条消息,所以首先要确定的就是向哪个分区发送,kafka 支持自动分配分区,也支持开发者自己指定分区。
分区是通过 Partitioner(分区器) 实现的,默认的分区器会看消息是否有 key:
- 如果有key,就计算key的hash值,然后对总分区数求模得到消息要被发送到的目标分区号。
- 如果没有key,会选择轮询的方式在各个分区上均匀分配。
2,producer 代码流程:
Producer首先使用一个线程(用户主线程,也即用户启动Producer的线程)将待发送的消息封装进一个ProducerRecord类实例,然后将其序列化之后发送给partitioner,再结合本地缓存的元数据信息由partitioner来确定目标分区后一同发送到位于producer程序中的一块内存缓冲区中。而KafkaProducer中的另一个专门的sender I/O线程则负责实时地从该缓冲区中提取出准备就绪的消息封装进一个批次(batch),统一发送给对应的broker。
3、构造producer实例大致步骤
1)构造一个java.util.Properties对象,然后至少指定bootstrap.servers 、key.serializer、value.serializer这三个属性。对于bootstrap.servers参数,若kafka集群中机器数很多,可只需指定部分broker即可,producer会通过该参数找到并发现集群中所有的broker。而kafka接收到的消息都是字节数组,所以对于key和value,必须先进行序列化,使用全限定包名“org.apache.kafka.common.serialization.StringDeserializer“,
2)构造KafkaProducer对象
3)构造待发送的消息对象ProducerRecord,指定消息要被发送到的topic、分区及对应的key和value。注意,分区和key信息可以不用指定,有kafka自行确定分区
4)调用KafkaProducer的send方法发送消息。
5)关闭KafkaProducer。producer程序结束时一定要关闭producer。提供有无参数的close方法和有超时参数close方法。在实际场景中,一定要慎用待超时参数的close方法。关闭原因是producer开了额外线程和socket连接等,必须要将其关闭,避免占用较多资源
4,生产者具体代码
import org.apache.kafka.clients.producer.*;
import org.apache.kafka.common.errors.RetriableException;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
/*
*/
public class ProducerTest {
public static void main(String[] args) {
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");//指定发往哪台broker服务器
props.put("key.serializer", "org.apache.kafka.common.serialization.StringDeserializer");//kafka发送给broker端的数据必须是字节数组
//所以kafafka首先对消息进行序列化,然后才能发送给broker
props.put(&