消息队列中间件——Kafka

文章目录

  • 1. 什么是消息队列
  • 2. Kafka的基本概念
  • 3. Kafka的Java生产者
    • 3.1 配置并创建生产者对象
    • 3.2 同步发送消息
    • 3.3 异步发送消息
  • 4. Kafka的Java消费者
    • 4.1 配置并创建消费者对象
    • 4.2 消费消息并手动同步的提交 offset
    • 4.3 消费消息手动异步的提交 offset
  • 5. Spring Boot整合Kafka
    • 5.1 添加依赖
    • 5.2 生产者的配置
    • 5.3 生产者代码
    • 5.4 消费者的配置
    • 5.5 消费者的代码
  • 6. Kafka常见面试题
    • 6.1 Kafka消息保存地方
    • 6.2 分区的作用
    • 6.3 Kafka集群中的controller
    • 6.4 Kafka集群的rebalance
    • 6.5 如何防止消息丢失
    • 6.6 如何防止重复消费
    • 6.7 如何做到顺序消费
    • 6.8 如何解决消息积压
    • 6.9 如何实现延迟队列效果

1. 什么是消息队列

消息队列的英文全称是 Message Queue,简称 MQ。MQ 的作用是通过将消息的发送和接收分离来实现应用程序的异步和解耦。但 MQ 的真正目的是为了通信,屏蔽底层复杂的通讯协议,定义了一套应用层的、更加简单的通信协议。
MQ 在这些协议之上构建一个简单的“协议”———生成者/消费者模型。它定义两个对象,发送消息的叫生产者,接收消息的叫消费者。提供一个 SDK 让我们可以定义自己的生产者和消费者实现消息通讯而无视底层通讯协议。

2. Kafka的基本概念

kafka 是一个分布式的、分区的消息服务。

相关的术语介绍:

  1. Broker:消息中间件处理节点,一个 kafka 节点就是一个 broker,一个或者多个 broker 可以组成一个 kafka 集群
  2. Topic:kafka 根据 topic 对消息进行归类,发布到kafka的消息都需要指定 topic
  3. Producer:消息生产者,向 broker 发送消息的客户端
  4. Consumer:消息消费者,从 broker 读取消息的客户端
  5. Consumer Group:每个 Consumer 都属于一个特定的 Consumer Group,一条消息可以被多个不同的 Consumer Group 消费,但是一个 Consumer Group 中只能有一个 Consumer 能够消费该消息
  6. Partition:物理上的概念,一个 topic 可以分为多个 partition,每个 partition 内部消息是有序的

3. Kafka的Java生产者

3.1 配置并创建生产者对象

Properties properties = new Properties();

// 配置 kafka 集群的 broker 的 ip 和 port
properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "ip:port, ip:port");

// 把发送的 key 字符串序列化成字节数组
properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());

// 把发送的 value 字符串序列化成字节数组
properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,StringSerializer.class.getName());

// ack 参数配置,默认是 1
// 0:生产者发送完消息后,kafka 立刻给生产者返回 ack,这种容易丢失消息,效率最高
// 1:多副本中的 leader 收到消息,并写入到本地的 log 文件中,才给生产者返回 ack,安全性和性能比较均衡
// -1:消息需要在所有 ISR 都同步成功后,才给生产者返回 ack,最安全,效率最低
properties.put(ProducerConfig.ACKS_CONFIG, 1);

// 指定重试的次数
properties.put(ProducerConfig.RETRIES_CONFIG, 3);

// 指定重试的间隔
properties.put(ProducerConfig.RETRY_BACKOFF_MS_CONFIG, 100);

// kafka 默认会创建一个消息缓存区,用来存放要发送的消息,默认大小是 32M
properties.put(ProducerConfig.BUFFER_MEMORY_CONFIG, 33554432);

// kafka 本地线程会从缓存区中一次拉取 16K 数据,发送给 broker
properties.put(ProducerConfig.BATCH_SIZE_CONFIG, 16384);

// 如果拉取不到 16K 数据,会间隔 10ms 后发送给 broker,默认是 0ms,这样影响性能,一般建议设置 10ms
properties.put(ProducerConfig.LINGER_MS_CONFIG, 10);

// 创建生产者客户端
KafkaProducer<String, String> kafkaProducer = new KafkaProducer<>(properties);

3.2 同步发送消息

// 创建一条消息,指定主题,消息的key,消息的内容,不指定分区是通过 key 的哈希运算计算出发到那个分区
ProducerRecord<String, String> record = new ProducerRecord<String, String>("topic", "key", "value");

// 发送消息并阻塞等待结果
try {
   
    // 发送消息
    Future<RecordMetadata> future = kafkaProducer.send(record);
    // get() 会阻塞直到 kafka 返回结果,或者抛异常
    RecordMetadata recordMetadata = future.get();
    System.out.

你可能感兴趣的:(Java,kafka,中间件,java)