次のような利用可能なシリアライザーはほとんどありません。
org.Apache.kafka.common.serialization.StringSerializer
org.Apache.kafka.common.serialization.StringSerializer
独自のカスタムシリアライザーを作成するにはどうすればよいですか?
ここに、Kafkaメッセージ値に独自のシリアライザー/デシリアライザーを使用する例があります。Kafkaメッセージキーも同じです。
MyMessageのシリアル化されたバージョンをKafka valueとして送信し、コンシューマー側のMyMessageオブジェクトに再度逆シリアル化します。
プロデューサー側でMyMessageをシリアル化します。
Org.Apache.kafka.common.serialization.Serializerを実装するシリアライザークラスを作成する必要があります
serialize()メソッドが作業を行い、オブジェクトを受け取り、シリアル化されたバージョンをバイト配列として返します。
public class MyValueSerializer implements Serializer<MyMessage>
{
private boolean isKey;
@Override
public void configure(Map<String, ?> configs, boolean isKey)
{
this.isKey = isKey;
}
@Override
public byte[] serialize(String topic, MyMessage message)
{
if (message == null) {
return null;
}
try {
(serialize your MyMessage object into bytes)
return bytes;
} catch (IOException | RuntimeException e) {
throw new SerializationException("Error serializing value", e);
}
}
@Override
public void close()
{
}
}
final IntegerSerializer keySerializer = new IntegerSerializer();
final MyValueSerializer myValueSerializer = new MyValueSerializer();
final KafkaProducer<Integer, MyMessage> producer = new KafkaProducer<>(props, keySerializer, myValueSerializer);
int messageNo = 1;
int kafkaKey = messageNo;
MyMessage kafkaValue = new MyMessage();
ProducerRecord producerRecord = new ProducerRecord<>(topic, kafkaKey, kafkaValue);
producer.send(producerRecord, new DemoCallBack(logTag, startTime, messageNo, strValue));
コンシューマ側でのMyMessageの逆シリアル化。
Org.Apache.kafka.common.serialization.Deserializerを実装するデシリアライザークラスを作成する必要があります
deserialize()メソッドが作業を行い、シリアル化された値をバイト配列として受け取り、オブジェクトを返します。
public class MyValueDeserializer implements Deserializer<MyMessage>
{
private boolean isKey;
@Override
public void configure(Map<String, ?> configs, boolean isKey)
{
this.isKey = isKey;
}
@Override
public MyMessage deserialize(String s, byte[] value)
{
if (value == null) {
return null;
}
try {
(deserialize value into your MyMessage object)
MyMessage message = new MyMessage();
return message;
} catch (IOException | RuntimeException e) {
throw new SerializationException("Error deserializing value", e);
}
}
@Override
public void close()
{
}
}
次に、次のように使用します。
final IntegerDeserializer keyDeserializer = new IntegerDeserializer();
final MyValueDeserializer myValueDeserializer = new MyValueDeserializer();
final KafkaConsumer<Integer, MyMessage> consumer = new KafkaConsumer<>(props, keyDeserializer, myValueDeserializer);
ConsumerRecords<Integer, MyMessage> records = consumer.poll(1000);
for (ConsumerRecord<Integer, MyMessage> record : records) {
int kafkaKey = record.key();
MyMessage kafkaValue = record.value();
...
}
言葉なし、コードのみ
あなたがカフカに送られるいくつかのオブジェクト
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class TestDto {
private String name;
private String version;
}
プロデューサーが使用するシリアライザーを作成します
@Slf4j
public class KafkaValueSerializer implements Serializer<TestDto> {
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public void configure(Map<String, ?> configs, boolean isKey) {
}
@Override
public byte[] serialize(String topic, TestDto data) {
try {
return objectMapper.writeValueAsBytes(data);
} catch (JsonProcessingException e) {
log.error("Unable to serialize object {}", data, e);
return null;
}
}
@Override
public void close() {
}
}
クーザーの、消費者のためのデシリアライザーについて気にしないでください
@Slf4j
public class KafkaValueDeserializer implements Deserializer<TestDto> {
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public void configure(Map<String, ?> configs, boolean isKey) {
}
@Override
public TestDto deserialize(String topic, byte[] data) {
try {
return objectMapper.readValue(new String(data, "UTF-8"), TestDto.class);
} catch (Exception e) {
log.error("Unable to deserialize message {}", data, e);
return null;
}
}
@Override
public void close() {
}
}
最後に、シリアライザー/デシリアライザーをapplication.ymlに追加します
spring:
kafka:
bootstrap-servers: 192.168.192.168:9092
producer:
value-serializer: com.package.service.kafka.KafkaValueSerializer
consumer:
group-id: groupId
value-deserializer: com.package.service.kafka.KafkaValueDeserializer
それで全部です。設定ファイルやタンボイリンで踊る必要はありません:)
送信
KafkaTemplate<String, TestDto> kafkaTemplate;
TestDto test = new TestDto("test name", "test-version");
kafkaTemplate.send(topic, testDto);
聴く
@KafkaListener(topics = "${ktp-agent.kafka.request-topic}", groupId = "${spring.kafka.consumer.group-id}")
public void listen(TestDto message) {
log.info("Received message '{}' from Kafka.", message.toString());
}