生产者工作流程
从创建一个ProducerRecord对象开始,ProducerRecord对象需要包含目标主题和要发送的内容,可以选择是否指定键或分区。在发送ProducerRecord对象时,生产者要把键值对象序列化成字节数组。
接下来,数据被传给分区器。如果之前在ProducerRecord对象里指定了分区,那么分区器就不会做任何事情,直接把指定的分区返回。,如果没有指定分区,那么分区器就会根据ProducerRecord对象的键来选择一个分区。选好分区以后,生产者就知道该往哪个主题和分区发送这条记录。
然后,这条件里被添加到一个记录批次里,这个批次里的所有消息会被发送到相同的主题和分区上。有一个独立的线程负责把这些记录批次发送到相应的broker上。
服务器在收到这些消息时会发挥一个响应。如果消息成功写入Kafka,就返回一个RecordMetaData对象,它包含了主题和分区信息,以及记录在分区里的偏移量。如果写入失败,则会返回一个错误。生产者在收到错误之后会尝试重新发送消息,几次之后如果还是失败,就会返回错误信息。
创建Kafka生产者
- 设置属性:
- bootstrap.servers:指定broker的地址清单,地址给事为host:port。多个用逗号隔开。不需要所有的broker,建议至少要两个,能保证一个宕机还有另一个可以连接到集群。
- key.serializer:key的序列化方式,必须被设置为一个实现了org.apache.kafka.common.serialization.StringSerializer接口的类,生产者会使用这个类把键对象序列化成字节数组。
- value.serializer:与key.serializer一致。
- 可选属性
- acks:指定多少个分区副本接收到消息,生产者菜认为消息写入成功。
- buffer.memory:设置生产者内存缓冲区的大小。
- compression.type:消息是否压缩,它制定了消息被发送给broker之前使用哪一种压缩算法进行压缩。
- retries:生产者发送消息之后收到临时错误,重试发送几次。每次重试之间等待100ms,可以通过retry.backoff.ms参数修改这个时间间隔。
- batch.size:多个消息发送到同一个分区时,该批次可用的内存大小。
- client.id:任意字符串,识别消息来源。
- max.in.flight.requests.per.connection:指定生产者在收到服务器响应之前可以发送多少个消息。它的值越高,就会占用越多内存,提升吞吐量。设置为1保证消息是按照发送的顺序写入服务器。
- timeout.ms、request.timeout.ms、metadata.fetch.timeout.ms:request.timeout.ms指定生产者在发送数据等待服务器返回响应时间;metadata.fetch.timeout.ms指定了生产者在获取元数据时等待服务器返回响应的时间;timeout.ms指定了broker等待同步副本返回消息确认的时间,与asks的配置相匹配。
- max.block.ms:指定调用send()方法或使用partitionsFor()方法获取元数据时生产者的阻塞时间。
- max.request.size:控制生产者请求大小。
- receive.buffer.bytes和send.buffer.bytes:这两个参数分别指定了TCP socket接收和发送数据包的缓冲区大小。
发送消息的三种方式
- 发送并忘记(fire-and-froget):可能丢消息
ProducerRecord<String, String> record = new ProducerRecord<>("CustomerCountry", "Precision Products", "France");
try {
producer.send(record);
} catch (Exception e) {
e.printStackTrace();
}
- 同步发送:使用send()方法发送消息,它会返回一个Future对象,调用get()方法进行等待,就可以知道是否发送成功。
ProducerRecord<String, String> record = new ProducerRecord<>("CustomerCountry", "Precision Products", "France");
try {
producer.send(record).get();
} catch (Exception e) {
e.printStackTrace();
}
- 异步发送:调用send()方法,并指定一个回调函数,服务器在返回响应时调用该函数。
private class DemoProducerCallback implements Callback {
@Override
public void onCompletion(RecordMetadata recordMetadata, Exception e) {
if (e != null) {
e.printStackTrace();
}
}
}
ProducerRecord<String, String> record = new ProducerRecord<>("CustomerCountry", "Biomedical Materials", "USA");
producer.send(record, new DemoProducerCallback());
快年底了。。。
回家面对七大姑、八大姨炮轰式的关于对象盘问咋办呢?
啊~!女神啊你在哪里啊?