Kafka 生产者客户端基本使用
必要的参数
bootstrap.servers
该参数为 broker
地址,不需要全部都填,因为 kafka
会从当前 broker
中获取其他 broker
信息。不过为了某个 broker
挂掉,一般填多个 broker
地址
key.serializer
消息 key
如何序列化
value.serializer
消息内容如何序列化
示例代码
1 | Properties properties = new Properties(); |
生产者拦截器
在消息发送前,对消息进行处理,该动作发生在序列化器
、分区器
之前。
实现 org.apache.kafka.clients.producer.ProducerInterceptor
接口,即可自定义拦截器
介绍一下接口定义的方法
ProducerRecord<K, V> onSend(ProducerRecord<K, V> record)
在消息发送之前,可以对消息进行处理
void onAcknowledgement(RecordMetadata metadata, Exception exception
消息被应答之前或者消息发送失败时被调用
void close()
producer
被关闭时,会调用
kafka 允许配置拦截器链,多个拦截器用 , 号隔开即可。
1 | properties.put(ProducerConfig.INTERCEPTOR_CLASSES_CONFIG, TestProducerInterceptor.class.getName() + "," + TestProducerInterceptor2.class.getName()); |
序列化
序列化发生在分区器
之前
实现 org.apache.kafka.common.serialization.StringSerializer
接口即可自定义序列化
介绍一下接口定义的方法
void configure(Map<String, ?> configs, boolean isKey)
在 StringSerializer
实现中,用于设置编码
byte[] serialize(String topic, String data)
定义如何序列化
void close()
producer
关闭时,被调用
分区器
实现 org.apache.kafka.clients.producer.Partitioner
即可自定义分区器
kafka 可按 key 进行哈希(MurmurHash2),将消息发往同一个分区。如果未指定 key,那么将会把消息发往随机的一个分区。
介绍一下接口定义的方法
int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster)
定义发往哪个分区;具体的实现可参考DefaultPartitioner
void close()
producer
关闭时,被调用
与 RocketMQ 异同
- 与
kafka
一致,rocketMQ
允许生产者将消息发送到指定的 ‘partition’ 中 rocketMQ
没有序列化器
的概念。消息内容由rocketMQ
自行序列化- 从个人目前的使用情况,
rocketMQ
也没有提供类似拦截器
概念 rocketMQ
提供了hock
以此在消息发送前,和消息发送后,对消息进行处理
例如:
1 | DefaultMQProducer producer = new DefaultMQProducer("default"); |