顺序保证
Kafka 可以保证同一个分区里的消息是有序的。也就是说,发送消息时,主题有且只有一个分区,同时生产者按照一定的顺序发送消息, broker 就会按照这个顺序把它们写入分区,消费者也会按照同样的顺序读取它们。
如果某些场景要求消息是有序的,那么消息是否写入成功也是很关键的,所以不建议把 retires 设为 0(不重试的话消息可能会因为连接关 闭等原因会丢) 。所以还是需要重试,同时把 max.in.flight.request.per.connection 设为 1,这样在生产者尝试发送第一批消息时,就不会有其他的消息发送给 broker 。不过这样会严重影响生产者的吞吐量,所以只有在对消息的顺序有严格要求的情况下才能这么做。
package org.example.ProducerConfig;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.example.config.BusiConst;
import java.util.Properties;
public class OrderKafkaProducer {
public static void main(String[] args) {
//生产者三个属性必须指定(broker地址清单、key和value的序列化器)
Properties properties = new Properties();
properties.put("bootstrap.servers","192.168.42.111:9092");
properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
//顺序消息的保证,只能有一个分区
//max.in.flight.requests.per.connection设置为1,这样生产者在尝试发送第一批消息时,就不会有其他的消息发送给其他broker
//默认值是5
properties.put("max.in.flight.requests.per.connection", 1);
KafkaProducer<String,String> producer = new KafkaProducer<String, String>(properties);
try {
ProducerRecord<String,String> record;
try {
//发送4条消息
for(int i=0;i<4;i++){
record = new ProducerRecord<String,String>(BusiConst.HELLO_TOPIC, String.valueOf(i),"Fisher");
producer.send(record);
System.out.println(i+",message is sent");
}
} catch (Exception e) {
e.printStackTrace();
}
} finally {
producer.close();
}
}
}