自定义Kafka拦截器

首先自定义Kafka拦截器,分为两种,一个是生产者拦截器,一个是消费者拦截器。

自定义生产者拦截器的步骤:

  1. 实现接口ProducerInterceptor<K,V>

  1. 实现以下四个方法:

public ProducerRecord<K, V> onSend(ProducerRecord<K, V> record)
public void onAcknowledgement(RecordMetadata metadata, Exception exception)
public void close()
public void configure(Map<String, ?> configs)

其中,onSend方法是实现拦截功能的主要方法。

下面是关于ProducerInterceptor接口和各个方法的介绍

ProducerInterceptor接口

ProducerInterceptor接口,是一个插件接口,允许您在生产者接收到的记录被发布到Kafka集群之前拦截(可能是突变)。这个类将通过configure()方法获取生产者配置属性,如果在生产者配置中没有指定,则包括KafkaProducer分配的clientId。拦截器实现需要意识到它将与其他拦截器和序列化器共享生产者配置名称空间,并确保没有冲突。由ProducerInterceptor方法抛出的异常将被捕获、记录,但不会进一步传播。因此,如果用户用错误的键和值类型参数配置拦截器,生成器不会抛出异常,只是记录错误。ProducerInterceptor回调可以从多个线程调用。如果需要,拦截器实现必须确保线程安全。实现ClusterResourceListener以在集群元数据可用时接收它。有关更多信息,请参阅ClusterResourceListener的类文档。

onSend()方法

它被KafkaProducer.send(ProducerRecord)和KafkaProducer.send(ProducerRecord, Callback)方法调用,在键和值被序列化和分区被分配之前(如果在ProducerRecord中没有指定分区)。

允许该方法修改记录,在这种情况下,将返回新记录。修改键/值意味着分区分配(如果没有在ProducerRecord中指定)将基于修改的键/值,而不是来自客户端的键/值。因此,在onSend()中完成的键和值转换需要是一致的:相同的键和值应该突变为相同的(修改后的)键和值。否则,日志压缩将无法正常工作。

类似地,由拦截器实现来确保在ProducerRecord中返回正确的主题/分区。大多数情况下,它应该是与'record'相同的主题/分区。

此方法抛出的任何异常都将被调用者捕获并记录,但不会进一步传播。

由于生产者可能运行多个拦截器,一个特定的拦截器的onSend()回调将按照ProducerConfig.INTERCEPTOR_CLASSES_CONFIG指定的顺序被调用。列表中的第一个拦截器获取客户端传递的记录,接下来的拦截器将获得前一个拦截器返回的记录,依此类推。由于拦截器被允许修改记录,拦截器可能会获得已经被其他拦截器修改过的记录。然而,不鼓励构建依赖于前一个拦截器输出的可变拦截器管道,因为拦截器可能会导致潜在的副作用,可能无法修改记录并引发异常。如果列表中的某个拦截器从onSend()抛出异常,则捕获该异常,记录该异常,并使用列表中最后一个成功拦截器或客户端返回的记录调用下一个拦截器。

传入的参数,是来自客户端的记录或拦截器链中前一个拦截器返回的记录。返回的是,发送到主题/分区的生产者记录。

onAcknowledgement()方法

当发送到服务器的记录已被确认,或者在发送到服务器之前发送记录失败时,将调用此方法。

这个方法通常在调用用户回调之前被调用,在KafkaProducer.send()抛出异常的情况下也会被调用。

调用者将忽略此方法抛出的任何异常。

此方法通常在后台I/O线程中执行,因此实现应该相当快。否则,从其他线程发送消息可能会被延迟。

传入的参数metadata ,是发送的记录的元数据(即分区和偏移量)。如果发生错误,元数据将只包含有效的主题和可能的分区。如果在ProducerRecord中没有给出partition,并且在分配partition之前发生了错误,那么partition将被设置为RecordMetadata.NO_PARTITION。如果客户端将空记录传递给KafkaProducer.send(ProducerRecord),则元数据可能为空。

close()方法

这个函数在拦截器关闭时调用

自定义消费者拦截器的步骤:

  1. 实现接口ConsumerInterceptor<K,V>

  1. 实现以下四个方法:

public ConsumerRecords<K, V> onConsume(ConsumerRecords<K, V> records)
public void onCommit(Map<TopicPartition, OffsetAndMetadata> offsets)
public void close()
public void configure(Map<String, ?> configs)

其中,onConsume方法是实现拦截功能的主要方法。

下面是关于ConsumerInterceptor接口和各个方法的介绍

ConsumerInterceptor<K,V>接口

一个插件接口,允许您拦截(并可能改变)消费者接收到的记录。一个主要的用例是第三方组件与使用者应用程序挂钩,以进行自定义监视、日志记录等。

这个类将通过configure()方法获取消费者配置属性,如果消费者配置中没有指定,则包括KafkaConsumer分配的clientId。拦截器实现需要意识到它将与其他拦截器和序列化器共享使用者配置名称空间,并确保没有冲突。

ConsumerInterceptor方法抛出的异常将被捕获、记录,但不会进一步传播。因此,如果用户使用错误的键和值类型参数配置拦截器,使用者将不会抛出异常,只是记录错误。

ConsumerInterceptor回调是从调用KafkaConsumer.poll(java.time.Duration)的同一个线程调用的。

实现ClusterResourceListener以在集群元数据可用时接收它。有关更多信息,请参阅ClusterResourceListener的类文档。

onConsume()方法

在kafkaconsumur .poll(java.time.Duration)返回记录之前调用。

此方法允许修改使用者记录,在这种情况下将返回新记录。此方法可以返回的记录数量没有限制。也就是说,拦截器可以过滤记录或生成新记录。

此方法抛出的任何异常都将被调用方捕获、记录,但不会传播到客户端。

由于消费者可能运行多个拦截器,一个特定的拦截器的onConsume()回调将按照ConsumerConfig.INTERCEPTOR_CLASSES_CONFIG指定的顺序被调用。列表中的第一个拦截器获取消耗的记录,接下来的拦截器将传递前一个拦截器返回的记录,依此类推。由于拦截器被允许修改记录,拦截器可能会获得已经被其他拦截器修改过的记录。然而,不鼓励构建依赖于前一个拦截器输出的可变拦截器管道,因为拦截器可能会导致潜在的副作用,可能无法修改记录并引发异常。如果列表中的一个拦截器从onConsume()抛出异常,则捕获该异常,记录该异常,并使用列表中最后一个成功的拦截器返回的记录(或者原始消耗的记录)调用下一个拦截器。

传入record,客户端要使用的记录或列表中前面的拦截器返回的记录。返回,被拦截器修改的记录或与传递给此方法的记录相同的记录。

onCommit()方法

在提交偏移量时调用此函数。

调用者将忽略此方法抛出的任何异常。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木林森先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值