Producer拦截器(Interceptor)是在kafka0.10版本被引入的,主要用于实现clients端(包括生产和消费)的定制化控制逻辑。对Producer来说,interceptor使得用户在消息发送前以及Producer回调逻辑前有机会对消息做一些定制化需求,比如修改消息。同时,Porducer允许用户指定多个interceptor按序作用于同一条消息上,从而形成一个拦截链。
关注微信公众号,获取更多内容
![在这里插入图片描述](https://img-blog.csdnimg.cn/20181107102704971.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYW5neGlvbmdjb2xpbg==,size_16,color_FFFFFF,t_70)
我们在调用KafkaProducer的send()方法时,就可以看到首先调用的是拦截器方法。
public Future send(ProducerRecord<K, V> record, Callback callback) {
// intercept the record, which can be potentially modified; this method does not throw exceptions
ProducerRecord<K, V> interceptedRecord = this.interceptors.onSend(record);
return doSend(interceptedRecord, callback);
}
intercaptors定义及初始化如下:
ProducerInterceptors<K, V> interceptors;
List<ProducerInterceptor<K, V>> interceptorList = (List) (new ProducerConfig(userProvidedConfigs, false)).getConfiguredInstances(ProducerConfig.INTERCEPTOR_CLASSES_CONFIG,
ProducerInterceptor.class);
this.interceptors = new ProducerInterceptors<>(interceptorList);
默认情况下是没有拦截器的
我们要实现自定义拦截器需要实现org.apache.kafka.clients.producer.ProducerInterceptor接口,
ProducerRecord<K, V> onSend(ProducerRecord<K, V> record):Producer确保在消息被序列化以计算分区前调用该方法。用户可以在该方法中对消息做任何操作,但最好不要修改消息所属的topic和分区,否则会影响目标分区的计算。
void onAcknowledgement(RecordMetadata metadata, Exception exception):该方法会在消息被应答之前或消息发送失败时调用,并且通常都是在Producer回调逻辑触发之前。
void close():关闭拦截器
我们在这里实现一个简单的带有两个interceptor组成的拦截链。一个interceptor会在消息发送前将时间戳信息加到消息value的尾部;另一个interceptor会在消息发送成功后更新成功发送消息数或失败发送消息数。
TimeStampInterceptor
package com.colin.beardata.kafka.producer.interceptor;
import org.apache.kafka.clients.producer.ProducerInterceptor;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;
import java.util.Map;
/**
-
Author: zhangxiong
-
Date: 18-8-5 下午5:45
-
Desc:
*/
public class TimeStampInterceptor implements ProducerInterceptor<String, String> {public ProducerRecord<String, String> onSend(ProducerRecord<String, String> producerRecord) {
return new ProducerRecord<String, String>(producerRecord.topic(),
producerRecord.partition(),
producerRecord.timestamp(),
producerRecord.key(),
producerRecord.value().toString() + “-” + System.currentTimeMillis());
}public void onAcknowledgement(RecordMetadata recordMetadata, Exception e) {
}
public void close() {
}
public void configure(Map<String, ?> map) {
}
}
CounterInterceptor:
package com.colin.beardata.kafka.producer.interceptor;
import org.apache.kafka.clients.producer.ProducerInterceptor;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;
import java.util.Map;
/**
-
Author: zhangxiong
-
Date: 18-8-5 下午5:48
-
Desc:
*/
public class CounterInterceptor implements ProducerInterceptor<String, String> {//发送成功消息数
private int successCounter = 0;
//发送失败消息数
private int failCounter = 0;public ProducerRecord<String, String> onSend(ProducerRecord<String, String> producerRecord) {
return producerRecord;
}public void onAcknowledgement(RecordMetadata recordMetadata, Exception e) {
if (e == null) {
successCounter++;
} else {
failCounter++;
}
}public void close() {
System.out.println(“发送成功消息数:” + successCounter);
System.out.println(“发送失败消息数:” + failCounter);
}public void configure(Map<String, ?> map) {
}
}
调用
List interceptors = new ArrayList();
interceptors.add(“com.colin.beardata.kafka.producer.interceptor.TimeStampInterceptor”);
interceptors.add(“com.colin.beardata.kafka.producer.interceptor.CounterInterceptor”);
props.put(“interceptor.classes”, interceptors);
Producer<String, String> producer = new KafkaProducer<String, String>(props);
for (int i = 0; i < 10; i++) {
producer.send(new ProducerRecord<String, String>("beardata", null, Integer.toString(i))).get();
System.out.println("send data:" + i + "");
}
producer.close();
以上就是关于kafka interceptor的介绍