在测试功能前需要先安装配置JDK、Zookeeper、Kafka。
./kafka-topics.sh --bootstrap-server localhost:9092 --create --topic mytopic1 --partitions 2 --replication-factor 1
# Kafka开发团队重写了ZooKeeper的Quorum控制器代码并嵌入到Kafka中。所以从v2.8版本开始,Kafka不再依赖ZooKeeper
# --bootstrap-server 常用的KafkaProducer和KafkaConsumer用来连接Kafka集群的入口参数,这个参数对应的值通常是Kafka集群中部分broker的地址,比如:host1:9092,host2:9092,不同的broker地址之间用逗号隔开。
# --topic 指定了所要创建主题的名称
# --partitions 指定了分区个数
# --replication-factor 指定了副本因子
# --create 创建主题的动作指令
./kafka-topics.sh --bootstrap-server localhost:9092 --list
./kafka-topics.sh --bootstrap-server localhost:9092 --describe --topic mytopic1
./kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic mytopic1
# --bootstrap-server 指定了链接Kafka集群地址
./kafka-console-producer.sh --broker-list localhost:9092 --topic mytopic1
# --broker-list 指定了链接的Kafka集群地址
public class ProducerFastStart {
// Kafka集群地址
private static final String brokerList = "localhost:9092";
// 主题名称
private static final String topic = "mytopic1";
public static void main(String[] args) {
Properties properties = new Properties();
// 设置key序列化器
properties.put("key.serializer","org.apache.kafka.common.serialization.StringSerializer");
// 设置重试次数
properties.put(ProducerConfig.RETRIES_CONFIG,10);
// 设置值序列化器
properties.put("value.serializer","org.apache.kafka.common.serialization.StringSerializer");
// 设置集群地址
properties.put("bootstrap.servers",brokerList);
// KafkaProducer 线程安全
KafkaProducer<String,String> producer = new KafkaProducer<>(properties);
ProducerRecord<String,String> record = new ProducerRecord<>(topic,"666","888");
try {
producer.send(record);
} catch (Exception e) {
}
producer.close();
}
}
public class ConsumerFastStart {
// Kafka集群地址
private static final String brokerList = "localhost:9092";
// 主题名称
private static final String topic = "mytopic1";
// 消费组
private static final String groupId = "group.demo";
public static void main(String[] args) {
Properties properties = new Properties();
// 设置key序列化器
properties.put("key.deserializer","org.apache.kafka.common.serialization.StringDeserializer");
// 设置值序列化器
properties.put("value.deserializer","org.apache.kafka.common.serialization.StringDeserializer");
// 设置集群地址
properties.put("bootstrap.servers",brokerList);
properties.put("group.id",groupId);
KafkaConsumer<String,String> consumer = new KafkaConsumer<>(properties);
consumer.subscribe(Collections.singletonList(topic));
while (true) {
ConsumerRecords<String,String> records = consumer.poll(Duration.ofMillis(1000));
for (ConsumerRecord<String,String> record : records) {
System.out.println(record.value());
}
}
}
}
这个参数用来指定分区中必须有多少个副本收到这条消息并发送确认,之后生产者才会认为这条消息写入成功。acks是生产者客户端中非常重要的一个参数,它涉及到消息的可靠性和吞吐量之间的权衡。
生产者从服务器收到的错误有可能是临时性的错误(比如分区找不到首领)。在这种情况下,如果达到了retries设置的次数,生产者会放弃重试并返回错误。默认情况下,生产者会在每次重试之间等待100ms,可以通过retries.backoff.ms参数来修改这个时间间隙。
当有多个消息要被发送到同一分区时,生产者会把它们放在同一个批次里。该参数指定了一个批次可以使用的内存大小,按照字节数计算,而不是消息个数。当批次被填满,批次里的所有消息会被发送出去。不过生产者并不一定都会等到批次被填满才发送,半满的批次,甚至只包含一个消息的批次也可能被发送。所以就算把batch.size设置的很大,也不会造成延迟,只会占用更多的内存而已,如果设置的太小,生产者会因为频繁发送消息而增加一些额外的开销。
该参数用于控制生产者发送的请求大小,它可以指定能发送的单个消息的最大值,也可以指单个请求里所有消息的总大小。broker对可接收的消息最大值也有自己的限制message.max.size,所以两边的配置最好匹配,避免生产者发送的消息被broker拒绝。