补充下mq作用:
降低系统耦合,异步, 削峰限流 ,
key.serializer
和value.serializer 序列化器
producer
consumer
broker : kafka实例
topic
partition:类似队列 ,且消息有序
partition可以处于不同broker,以此达到负载均衡等
template.send( key , value) , key用于指定分区
已提交
的位置是已安全保存的最后偏移量,如果进程失败或重新启动时,消费者将恢复到这个偏移量。消费者可以选择定期自动提交偏移量,也可以选择通过调用commit API来手动的控制(如:commitSync
和 commitAsync
偏移量,消费者组(⚠️
发送到Topic的消息,只会被订阅此Topic的每个group中的一个consumer消费。(分区会被分配给消费者组中的唯一消费者)
这样,一个分区的消费者都是不同组的
发现消费者故障
消费者向服务器定时发送心跳,session.timeout.ms
kafka 提供了分区多副本: leader副本, follower副本
Kafka 怎么做到消息顺序消费?
首先partition有序,
- (推荐)发送消息的时候指定 key。根据这个 key 的哈希值来决定消息应该被发送到哪个 Partition。这样,相同的 key 将始终被发送到同一个 Partition
kafka消息可靠性?
1.生产者丢失消息的情况
ListenableFuture 设置回调函数
ListenableFuture<SendResult<String, Object>> future = kafkaTemplate.send(topic, o); future.addCallback(
result -> logger.info("生产者成功发送消息到topic:{} partition:{}的消息",
result.getRecordMetadata().topic(), result.getRecordMetadata().partition()), ex -> logger.error("生产者发送消失败,原因:{}", ex.getMessage()));
2.消费者丢失消息
手动提交offset(
3.kakfa丢失消息
leader挂了换leader时, 一些数据没有被 follower 副本的同步的话,就会造成消息丢失
设置 acks = all,所有 ISR 列表的副本全部收到消息时,生产者才会接收到来自服务器的响应
即任何一个副本(不在 ISR 列表中)没有成功接收到消息,生产者都不会收到成功的响应
kafka保证不重复消费
1. 消费消息服务做幂等校验
2.enable.auto.commit =false ,
开发者在代码中手动提交 offset
什么时候提交 offset 合适?业务忙的时候提交offset,但没有处理业务,而是写日志等,之后再处理
kafka可以实现幂等和事务
producer.beginTransaction(); for (int i = 0; i < 100; i++) producer.send(new ProducerRecord<>("my-topic", Integer.toString(i), Integer.toString(i))); producer.commitTransaction();
Kafka 的重试机制主要分为生产者和消费者两端。生产者通过 retries
参数控制重试次数,消费者可以通过手动管理 offset 或配合 Spring Kafka 的重试机制来处理消费失败的情况