通信メッセージフォーマットカフカ

1.シリアルメッセージ

キーメッセージと値があります。

カフカは、カスタムクラスのサービスのためのデータ型ツールのシーケンスのための基礎は、自己のシリアル化を達成するために必要提供します

KVとヘッダーを含むProducerRecordオブジェクト、またはこの場合のオブジェクトKV

KVはKVのバイト配列を取得するためにKafkaProducer#doSendでシリアル化されます

その後、ヘッダーとProducerBatchのバイト配列に追加

コードは、以下を参照してください。

org.apache.kafka.clients.producer.internals.ProducerBatch#recordsBuilder 
org.apache.kafka.common.record.MemoryRecordsBuilder#appendStream

 

TCPパケットの2カフカ

スキーマ構造体を使用してProducerBatch TCPパケットマッチング形式カフカにデータを変換します

例えば、メッセージを送信するには

org.apache.kafka.common.requests.AbstractRequest#toSend 
org.apache.kafka.common.requests.AbstractRequest#シリアライズの
org.apache.kafka.common.requests.AbstractRequestResponse位シリアライズ
org.apache.kafka.common.requests.ProduceRequestを#toStruct 
org.apache.kafka.common.protocol.types.Schema番号の書き込み

org.apache.kafka.common.requests.RequestHeader#toStruct

パブリック構造体toStruct(){ 
    スキーマのスキーマ = スキーマ(apiKey.id、apiVersion)。
    構造体構造体 = 新しい構造体(スキーマ)。
    struct.set(API_KEY_FIELD_NAME、apiKey.id)。
    struct.set(API_VERSION_FIELD_NAME、apiVersion)。

    // のみ制御されたシャットダウン要求のV0のclientIdが欠落している
    場合(struct.hasField(CLIENT_ID_FIELD_NAME))
        struct.set(CLIENT_ID_FIELD_NAME、のclientId); 
    struct.set(CORRELATION_ID_FIELD_NAME、correlationIdに)。
    戻り値の構造体。
}

org.apache.kafka.common.requests.ProduceRequest#toStruct

パブリック構造体toStruct(){
     // 同時更新から保護するために、ローカル変数に格納 
    地図<TopicPartition、MemoryRecords> partitionRecords = partitionRecordsOrFail();
    短いバージョン= バージョン()。
    構造体構造体 = 新しい構造体(ApiKeys.PRODUCE.requestSchema(バージョン)); 
    地図 <文字列、地図<Integer型、MemoryRecords >> recordsByTopic = CollectionUtils.groupDataByTopic(partitionRecords)。
    struct.set(ACKS_KEY_NAME、ACKの); 
    struct.set(TIMEOUT_KEY_NAME、タイムアウト)。
    struct.setIfExists(NULLABLE_TRANSACTIONAL_ID、transactionalId)。

    リストの<struct> topicDatas =新しいのArrayList <> (recordsByTopic.size());
    (のMap.Entry <文字列、マップ<整数、MemoryRecords >> topicEntry:recordsByTopic.entrySet()){ 
        構造体topicData = struct.instance(TOPIC_DATA_KEY_NAME)。
        topicData.set(TOPIC_NAME、topicEntry.getKey())。
        リストの<struct> partitionArray = 新しい ArrayListを<> ();
        (のMap.Entry <整数、MemoryRecords> partitionEntry:topicEntry.getValue()のentrySet()){ 
            MemoryRecordsレコード = partitionEntry.getValue()。
            構造体の一部 = topicData。
                    .SET(PARTITION_ID、partitionEntry.getKey())
                    .SET(RECORD_SET_KEY_NAME、レコード)。
            partitionArray.add(部分)。
        } 
        topicData.set(PARTITION_DATA_KEY_NAME、partitionArray.toArray())。
        topicDatas.add(topicData)。
    } 
    struct.set(TOPIC_DATA_KEY_NAME、topicDatas.toArray())。
    戻り値の構造体。
}

パケットの組み立て

パブリック 抽象 クラスAbstractRequestResponse {
     / ** 
     *テストのために目に見えます。
     * / 
    パブリック 静的のByteBufferのシリアライズ(構造体headerStruct、構造体bodyStruct){ 
        ByteBufferのバッファ = ByteBuffer.allocate(headerStruct.sizeOf()+ bodyStruct.sizeOf())。
        headerStruct.writeTo(バッファ)
        bodyStruct.writeTo(バッファ)
        buffer.rewind(); 
        リターンバッファ; 
    } 
} 

パブリック クラス NetworkSendが延びByteBufferSend { 

    公共NetworkSend(文字列先、ByteBufferのバッファ){
         スーパー(宛先、sizeDelimit(緩衝液))。
    } 

    プライベート 静的のByteBuffer [] sizeDelimit(ByteBufferの緩衝液){
         戻り 新規のByteBuffer [] {sizeBuffer(buffer.remaining())、バッファ}。
    } 

    プライベート 静的のByteBuffer sizeBuffer(int型のサイズ){ 
        ByteBufferのsizeBuffer = ByteBuffer.allocate(4 )。
        sizeBuffer.putInt(サイズ)。
        sizeBuffer.rewind(); 
        返すsizeBufferを。
    } 

}

カフカのメッセージフォーマットを推測することが可能である:4バイトの記憶領域の長さ、headerStruct、bodyStruct

もちろん、NetworkSendやコメントでもNetworkReceive見ることができます

おすすめ

転載: www.cnblogs.com/allenwas3/p/11626980.html