Kafka 0.8.1。でPOCを構築しようとしています。自分のJavaクラスをKafka一連の文字列データ型を含むメッセージです。デフォルトのシリアライザクラスまたはKafkaライブラリに付属する文字列シリアライザクラスを使用できません。独自のシリアライザを作成してフィードする必要があると思いますプロデューサーのプロパティ。Kafka(Javaの場合)でカスタムシリアライザーの例を書くことに気づいている場合は、共有してください。ありがとうございました。
カスタムシリアライザーを作成するために必要なものは次のとおりです。
Encoder
を実装しますVerifiableProperties
コンストラクタを指定する必要がありますtoBytes(...)
メソッドをオーバーライドして、バイト配列が返されることを確認しますProducerConfig
に挿入します質問で述べたように、Kafkaは、プロデューサの特定のシリアライザを宣言する手段を提供します。シリアライザクラスはProducerConfig
インスタンスに設定され、そのインスタンスは必要なProducer
クラス。
Kafkaのプロデューサーの例 に従う場合、ProducerConfig
オブジェクトを介してProperties
を構築します。プロパティファイルをビルドするときは、必ず以下を含めてください。
props.put("serializer.class", "path.to.your.CustomSerializer");
Kafkaを使用して、メッセージをログに追加する前にメッセージをシリアル化するために使用するクラスへのパスを指定します。
Kafkaが適切に解釈できるカスタムシリアライザを作成するには、Encoder[T]
scala that that Kafkaが提供するクラスを実装する必要があります。 Javaは奇妙です に特性を実装していますが、次のメソッドは私のプロジェクトでJSONをシリアル化するために機能しました:
public class JsonEncoder implements Encoder<Object> {
private static final Logger logger = Logger.getLogger(JsonEncoder.class);
// instantiating ObjectMapper is expensive. In real life, prefer injecting the value.
private static final ObjectMapper objectMapper = new ObjectMapper();
public JsonEncoder(VerifiableProperties verifiableProperties) {
/* This constructor must be present for successful compile. */
}
@Override
public byte[] toBytes(Object object) {
try {
return objectMapper.writeValueAsString(object).getBytes();
} catch (JsonProcessingException e) {
logger.error(String.format("Json processing failed for object: %s", object.getClass().getName()), e);
}
return "".getBytes();
}
}
あなたの質問は、ログに追加されたすべてのメッセージに対して1つのオブジェクト(CustomMessage
と呼ぶことにします)を使用しているように聞こえます。その場合、シリアライザは次のようになります。
package com.project.serializer;
public class CustomMessageEncoder implements Encoder<CustomMessage> {
public CustomMessageEncoder(VerifiableProperties verifiableProperties) {
/* This constructor must be present for successful compile. */
}
@Override
public byte[] toBytes(CustomMessage customMessage) {
return customMessage.toBytes();
}
}
プロパティ設定は次のようになります。
props.put("serializer.class", "path.to.your.CustomSerializer");
エンコードとデコーダの両方を実装する必要がある
public class JsonEncoder implements Encoder<Object> {
private static final Logger LOGGER = Logger.getLogger(JsonEncoder.class);
public JsonEncoder(VerifiableProperties verifiableProperties) {
/* This constructor must be present for successful compile. */
}
@Override
public byte[] toBytes(Object object) {
ObjectMapper objectMapper = new ObjectMapper();
try {
return objectMapper.writeValueAsString(object).getBytes();
} catch (JsonProcessingException e) {
LOGGER.error(String.format("Json processing failed for object: %s", object.getClass().getName()), e);
}
return "".getBytes();
}
}
デコーダーコード
public class JsonDecoder implements Decoder<Object> {
private static final Logger LOGGER = Logger.getLogger(JsonEncoder.class);
public JsonDecoder(VerifiableProperties verifiableProperties) {
/* This constructor must be present for successful compile. */
}
@Override
public Object fromBytes(byte[] bytes) {
ObjectMapper objectMapper = new ObjectMapper();
try {
return objectMapper.readValue(bytes, Map.class);
} catch (IOException e) {
LOGGER.error(String.format("Json processing failed for object: %s", bytes.toString()), e);
}
return null;
}
}
Pomエントリ
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.1.3</version>
</dependency>
Kafkaプロパティにデフォルトのエンコーダーを設定します
properties.put("serializer.class","kafka.serializer.DefaultEncoder");
ライターとリーダーのコードは次のとおりです
byte[] bytes = encoder.toBytes(map);
KeyedMessage<String, byte[]> message =new KeyedMessage<String, byte[]>(this.topic, bytes);
JsonDecoder decoder = new JsonDecoder(null);
Map map = (Map) decoder.fromBytes(it.next().message());