Apache kafka 发布和使用不同类型消息的最佳方式是什么?

Apache kafka 发布和使用不同类型消息的最佳方式是什么?,apache-kafka,kafka-consumer-api,kafka-producer-api,Apache Kafka,Kafka Consumer Api,Kafka Producer Api,卡夫卡0.8V 我想发布/使用byte[]对象、JavaBean对象、可序列化对象等等 对于这种类型的场景,定义发布者和使用者的最佳方法是什么? 当我使用来自使用者迭代器的消息时,我不知道它是什么类型的消息。 有谁能给我一个关于如何设计这种场景的指南吗?我对每个卡夫卡主题强制执行一个模式或对象类型。这样,当你收到信息时,你就能确切地知道你收到了什么 至少,您应该决定给定的主题是要保存二进制还是字符串数据,并根据这一点决定如何对其进行进一步编码 例如,您可以有一个名为Schema的主题,其中包含存

卡夫卡0.8V

我想发布/使用byte[]对象、JavaBean对象、可序列化对象等等

对于这种类型的场景,定义发布者和使用者的最佳方法是什么? 当我使用来自使用者迭代器的消息时,我不知道它是什么类型的消息。
有谁能给我一个关于如何设计这种场景的指南吗?

我对每个卡夫卡主题强制执行一个模式或对象类型。这样,当你收到信息时,你就能确切地知道你收到了什么

至少,您应该决定给定的主题是要保存
二进制
还是
字符串
数据,并根据这一点决定如何对其进行进一步编码

例如,您可以有一个名为Schema的主题,其中包含存储为字符串的
JSON
-编码对象

如果您使用
JSON
和类似JavaScript的松散类型语言,那么在同一主题中存储具有不同模式的不同对象是很有诱惑力的。使用JavaScript,您只需调用
JSON.parse(…)
,查看生成的对象,并找出要对其执行的操作

但是,在像Scala这样的严格类型语言中,您无法做到这一点。Scala JSON解析器通常希望您将JSON解析为已定义的Scala类型,通常是
case类
。它们不适用于此模型

一种解决方案是保持一个模式/一个主题的规则,但要有点欺骗:将对象包装在对象中。一个典型的例子是一个Action对象,其中有一个描述该动作的头,以及一个模式依赖于头中列出的动作类型的payload对象。想象一下这个伪模式:

{name: "Action", fields: [
  {name: "actionType", type: "string"},
  {name: "actionObject", type: "string"}
]}
这样,即使在强类型语言中,您也可以执行以下操作(这也是伪代码):

这种方法的一个巧妙之处是,如果您的消费者只等待一个特定的
动作.actionType
,而忽略了其他所有动作,那么它只解码头并推迟解码
动作.actionObject
,直到需要时才解码,这是非常轻量级的

到目前为止,这些都是关于字符串编码的数据。如果您想处理二进制数据,当然也可以将其包装为JSON,或者任何一种基于字符串的编码,如XML。但是也有一些二进制编码系统,比如Thrift和。事实上,上面的伪模式是基于Avro的。你甚至可以在Avro中做一些很酷的事情,比如模式演化,它提供了一种非常灵活的方法来处理上述
操作
用例——你可以定义一个模式,它是其他模式的子集,并只解码你想要的字段,而不是将一个对象包装在一个对象中,在本例中,仅显示
action.actionType
字段。下面是对的非常出色的描述

简而言之,我的建议是:

  • 选择基于模式的编码系统(可以是JSON、XML、Avro、, (随便)
  • 强制每个主题一个架构规则

  • 谢谢大卫这么清楚的解释。我是卡夫卡的新手。我检查Avro模式。我可以从收到的字节中获取模式吗?因为我将有数百个主题,从接收方线程,我如何识别要应用的模式?不,你不能直接从接收到的字节中获取模式——它不携带模式。Avro的“常用”方法是将模式与编码记录一起存储在文件中,但这在流式环境中不起作用。相反,正如上面提到的,我只针对Avro模式使用一个单独的主题。消费者在我的系统中做的第一件事就是从一开始就听这个主题,并以这种方式使用适当的模式来配置自己。
    action = JSONParser[Action].parse(msg)
    switch(action.actionType) {
      case "foo" => var foo = JSONParser[Foo].parse(action.actionObject)
      case "bar" => var bar = JSONParser[Bar].parse(action.actionObject)
    }