Kafka中消息的生产与消费示例

在测试功能前需要先安装配置JDK、Zookeeper、Kafka。

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集群地址

Java形式

  • 首先添加依赖。
  • 创建生产者:
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

这个参数用来指定分区中必须有多少个副本收到这条消息并发送确认,之后生产者才会认为这条消息写入成功。acks是生产者客户端中非常重要的一个参数,它涉及到消息的可靠性和吞吐量之间的权衡。

  • ack=0,生产者在成功写入消息之前不会等待任何来自服务器的响应。如果出现问题生产者是感知不到的,消息就丢失了。不过因为生产者不需要等待服务器响应,所以它可以以网络能够支持的最大速度发送消息,从而达到很高的吞吐量。
  • ack=1,默认值是1,只要集群的首领节点收到消息,生产者就会收到一个来自服务器的成功响应。如果消息无法达到首领节点(比如首领节点崩溃,新的首领节点还没有被选举出来)。生产者会收到一个错误响应,为了避免数据丢失,生产者会重发消息。但是,这样有可能会导致数据丢失,如果收到写成功通知,此时首领节点还没来得及同步数据到follower节点,首领节点崩溃,就会导致数据丢失。
  • ack=-1,只有当所有参与复制的节点都收到消息时,生产者会收到一个来自服务器的成功响应,这种模式是最安全的,它可以保证不止一个服务器收到消息。

retries

生产者从服务器收到的错误有可能是临时性的错误(比如分区找不到首领)。在这种情况下,如果达到了retries设置的次数,生产者会放弃重试并返回错误。默认情况下,生产者会在每次重试之间等待100ms,可以通过retries.backoff.ms参数来修改这个时间间隙。

batch.size

当有多个消息要被发送到同一分区时,生产者会把它们放在同一个批次里。该参数指定了一个批次可以使用的内存大小,按照字节数计算,而不是消息个数。当批次被填满,批次里的所有消息会被发送出去。不过生产者并不一定都会等到批次被填满才发送,半满的批次,甚至只包含一个消息的批次也可能被发送。所以就算把batch.size设置的很大,也不会造成延迟,只会占用更多的内存而已,如果设置的太小,生产者会因为频繁发送消息而增加一些额外的开销。

max.request.size

该参数用于控制生产者发送的请求大小,它可以指定能发送的单个消息的最大值,也可以指单个请求里所有消息的总大小。broker对可接收的消息最大值也有自己的限制message.max.size,所以两边的配置最好匹配,避免生产者发送的消息被broker拒绝。

你可能感兴趣的:(kafka,kafka,java,分布式)