⚙️ 如何调整重试策略以适应不同的业务需求?

ops/2024/11/14 6:33:12/

调整 Kafka 生产者和消费者的重试策略以适应不同的业务需求,需要根据业务的特性和容错要求来进行细致的配置。以下是一些关键的调整策略:

  1. 业务重要性

    • 对于关键业务消息,可以增加重试次数,并设置较长的重试间隔,以减少消息丢失的风险。
    • 对于非关键业务消息,可以减少重试次数或不进行重试,以避免不必要的资源消耗。
  2. 消息幂等性

    • 如果业务逻辑是幂等的,即多次处理相同消息不会导致业务状态不一致,可以增加重试次数。
    • 如果业务逻辑不是幂等的,需要谨慎设置重试策略,或者实现去重逻辑。
  3. 消息时效性

    • 对于时效性要求高的消息,可以减少重试间隔,以便快速尝试重新发送。
    • 对于时效性要求不高的消息,可以增加重试间隔,减少对 Kafka 集群的压力。
  4. 系统容量和负载

    • 根据 Kafka 集群和下游系统的容量和负载情况调整重试策略,避免因重试导致的额外负载影响系统稳定性。
  5. 错误类型

    • 对于临时性错误(如网络问题),可以设置较高的重试次数和较短的重试间隔。
    • 对于永久性错误(如消息格式错误),应减少重试次数,避免无意义的重试。
  6. 死信队列(DLQ)

    • 对于重试次数用尽后仍然发送失败的消息,可以配置死信队列进行存储,以便后续分析和处理。
  7. 监控和告警

    • 实施实时监控,对重试次数、失败率等关键指标进行监控,并设置告警阈值。
  8. 业务流程控制

    • 在业务流程中实现重试逻辑,例如在业务层捕获异常并根据业务规则进行重试。
  9. 自定义重试策略

    • 实现自定义的重试策略,例如指数退避策略,以适应特定的业务场景。
  10. 事务性消息

    • 如果业务要求消息发送的原子性,可以启用事务性消息发送,确保消息要么全部发送成功,要么全部不发送。
  11. 资源限制

    • 考虑到生产者和消费者的资源限制,如内存和网络带宽,合理设置重试策略,避免资源耗尽。
  12. 反馈机制

    • 建立反馈机制,根据业务运行情况和系统性能反馈调整重试策略。

通过综合考虑上述因素,可以为不同的业务需求定制合适的重试策略,以确保 Kafka 消息系统的高效性和可靠性。

在这里插入图片描述

以下是一些代码案例,展示了如何根据不同的业务需求调整 Kafka 生产者和消费者的重试策略

在这里插入图片描述

Kafka 生产者重试策略案例

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.serialization.StringSerializer;import java.util.Properties;public class CustomRetryProducerDemo {public static void main(String[] args) {// 配置生产者属性Properties props = new Properties();props.put("bootstrap.servers", "4.5.8.4:9092");props.put("key.serializer", StringSerializer.class.getName());props.put("value.serializer", StringSerializer.class.getName());props.put("retries", 5); // 设置重试次数props.put("retry.backoff.ms", 1000); // 设置重试间隔为1秒props.put("buffer.memory", 33554432); // 设置缓冲区大小props.put("batch.size", 16384); // 设置批次大小props.put("linger.ms", 10); // 设置等待时间为10毫秒props.put("max.in.flight.requests.per.connection", 1); // 设置最大在途请求数// 创建生产者实例Producer<String, String> producer = new KafkaProducer<>(props);// 发送消息for (int i = 0; i < 100; i++) {String key = "key-" + i;String value = "value-" + i;ProducerRecord<String, String> record = new ProducerRecord<>("test-topic", key, value);producer.send(record, (metadata, exception) -> {if (exception != null) {// 处理消息发送失败的情况System.err.println("发送消息失败:" + exception.getMessage());} else {// 处理消息发送成功的情况System.out.println("消息发送成功,偏移量:" + metadata.offset());}});}// 关闭生产者producer.close();}
}

Kafka 消费者重试策略案例

import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.common.serialization.StringDeserializer;import java.time.Duration;
import java.util.Collections;
import java.util.Properties;public class CustomRetryConsumerDemo {public static void main(String[] args) {// 配置消费者属性Properties props = new Properties();props.put("bootstrap.servers", "4.5.8.4:9092");props.put("group.id", "test-group");props.put("enable.auto.commit", "true");props.put("auto.commit.interval.ms", "1000");props.put("key.deserializer", StringDeserializer.class.getName());props.put("value.deserializer", StringDeserializer.class.getName());props.put("max.poll.records", 500); // 设置每次拉取的最大记录数props.put("fetch.min.bytes", 1024); // 设置最小获取1KB的数据props.put("fetch.max.wait.ms", 500); // 设置最大等待500ms// 创建消费者实例Consumer<String, String> consumer = new KafkaConsumer<>(props);// 订阅主题consumer.subscribe(Collections.singletonList("test-topic"));// 消费消息while (true) {ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));for (ConsumerRecord<String, String> record : records) {try {// 处理消息System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value());// 假设处理消息可能会失败if (record.value().contains("error")) {throw new RuntimeException("模拟处理消息失败");}} catch (Exception e) {// 处理消息失败,记录日志或重试System.err.println("处理消息失败:" + e.getMessage());// 可以在这里实现重试逻辑,例如将消息发送到死信队列}}// 批量提交偏移量consumer.commitSync();}}
}

死信队列(DLQ)案例

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.serialization.StringSerializer;import java.util.Properties;public class DLQProducerDemo {public static void main(String[] args) {// 配置生产者属性Properties props = new Properties();props.put("bootstrap.servers", "4.5.8.4:9092");props.put("key.serializer", StringSerializer.class.getName());props.put("value.serializer", StringSerializer.class.getName());props.put("retries", 5); // 设置重试次数props.put("retry.backoff.ms", 1000); // 设置重试间隔为1秒// 创建生产者实例Producer<String, String> producer = new KafkaProducer<>(props);// 发送消息for (int i = 0; i < 100; i++) {String key = "key-" + i;String value = "value-" + i;ProducerRecord<String, String> record = new ProducerRecord<>("test-topic", key, value);producer.send(record, (metadata, exception) -> {if (exception != null) {// 处理消息发送失败的情况System.err.println("发送消息失败:" + exception.getMessage());// 将失败的消息发送到死信队列ProducerRecord<String, String> dlqRecord = new ProducerRecord<>("test-topic-DLQ", key, exception.getMessage());producer.send(dlqRecord);} else {// 处理消息发送成功的情况System.out.println("消息发送成功,偏移量:" + metadata.offset());}});}// 关闭生产者producer.close();}
}

这些代码案例展示了如何根据不同的业务需求调整 Kafka
生产者和消费者的重试策略,包括设置重试次数、重试间隔、处理消息发送失败的情况以及实现死信队列(DLQ)。希望这些示例能帮助您更好地理解和应用
Kafka 的重试机制。


http://www.ppmy.cn/ops/133485.html

相关文章

【计算机网络】【传输层】【习题】

计算机网络-传输层-习题 文章目录 10. 图 5-29 给出了 TCP 连接建立的三次握手与连接释放的四次握手过程。根据 TCP 协议的工作原理&#xff0c;请填写图 5-29 中 ①~⑧ 位置的序号值。答案技巧 注&#xff1a;本文基于《计算机网络》&#xff08;第5版&#xff09;吴功宜、吴英…

PHP接口安全的机制

PHP接口安全的机制是一个多层次、综合性的防护体系&#xff0c;旨在确保接口数据的安全性和完整性。以下是对PHP接口安全机制的详细简述&#xff1a; 一、身份验证与授权 Token授权机制&#xff1a; 用户使用用户名和密码登录后&#xff0c;服务器会生成一个Token并返回给客户…

数据结构题集-第二章-线性表-有序单链表的交集

有序单链表的交集 说明2.26 假设两个元素依值递增有序排列的单链表A和B 说明 本文参照严蔚敏《数据结构(C语言版)题集》一书中包含的问答题和算法设计题目&#xff0c;提供解答和算法的解决方案。请读者在自己已经解决了某个题目或进行了充分的思考之后&#xff0c;再参考本解…

XMLHttpRequest以及Promise对象的使用

AJAX原理 通过[XHR]XMLHttpRequest对象来和服务器进行交互&#xff0c;axios库的底层也是通过XMLHttpRequest来和服务器进行交互&#xff0c;只是将实现细节进行了封装&#xff0c;让操作更加简洁 可以用于某些只需和服务器进行少次交互的静态网站进行使用&#xff0c;减少代…

three.js 杂记

clip&#xff1a; 1&#xff1a; 着色器 #ifdef USE_CLIP_DISTANCE vec4 worldPosition modelMatrix * vec4( position, 1.0 ); gl_ClipDistance[ 0 ] worldPosition.x - sin( time ) * ( 0.5 ); #endif gl_Position projectionMatrix * modelViewMatrix * vec4( positio…

CNN中每一层的权重是一样的么?

在卷积神经网络&#xff08;CNN&#xff09;中&#xff0c;每一层的权重并不是完全相同的&#xff0c;但在同一层内是共享的。具体来说&#xff0c;CNN的权重共享机制是指&#xff1a;在卷积层中&#xff0c;同一卷积核&#xff08;filter&#xff09;在输入图像的不同区域进行…

微擎框架php7.4使用phpexcel导出数据报错修复

在使用微擎社区版时&#xff0c;用phpexcel导出数据&#xff0c;提示错误&#xff0c;经过搜索后得知是php版本问题。 之前一直是用的5.6现在改成了7.4。所以才发现了这个问题。 然后去gitee上看了下微擎官方的代码&#xff0c;好像也没有对这个问题进行修复。 找了下&#…

【蓝桥杯 2021 省 B2】特殊年份

题目描述&#xff1a; 今年是 2021 年&#xff0c;2021 这个数字非常特殊, 它的千位和十位相等, 个位比百位大 1&#xff0c;我们称满足这样条件的年份为特殊年份。 输入 5 个年份&#xff0c;请计算这里面有多少个特殊年份。 输入格式 输入 5 行&#xff0c;每行一个 4 位十…