【问题标题】:Is it Possible to send a Java Object to C# App using Kafka是否可以使用 Kafka 将 Java 对象发送到 C# App
【发布时间】:2021-04-27 01:25:09
【问题描述】:

是否可以将 Java 对象(比如说用户)发送到一个主题,该主题在 C# 中被消费并序列化为用户对象?

假设我有以下从 Java PoJo 构建的 avro 模式(字段是名称和年龄)

{
  "namespace": "io.confluent.developer",
  "type": "record",
  "name": "User",
  "fields": [
    {
      "name": "name",
      "type": [
        "null",
        "string"
      ],
      "default": null
    },
    {
      "name": "age",
      "type": [
        "null",
        "int"
      ],
      "default": null
    }
  ]
}

生成一个 User.class

然后像这样发送:

Service
@CommonsLog(topic = "Producer Logger")
@RequiredArgsConstructor
public class Producer {

  @Value("${topic.name}")
  private String TOPIC;

  private final KafkaTemplate<String, User> kafkaTemplate;

  void sendMessage(User user) {
    this.kafkaTemplate.send(this.TOPIC, user.getName(), user);
    log.info(String.format("Produced user -> %s", user));
  }
}

我也有一个 Schema 注册表,但我不知道如何在 C# 中使用该消息并将其反序列化为具有相同字段的 User 类:

public class Users

{

    public int id = 0;

    public string name = string.Empty;

    public Users()

    {

        // Constructor Statements

    }

    public void GetUserDetails(int uid, string uname)

    {

        id = uid;

        uname = name;

        Console.WriteLine("Id: {0}, Name: {1}", id, name);

    }

    public int Designation { get; set; }

    public string Location { get; set; }

}

感谢您的帮助。

【问题讨论】:

    标签: java c# spring-boot apache-kafka confluent-schema-registry


    【解决方案1】:

    是的,这是可能的。您可以使用official .NET kafka client 来消费消息。

    您要做的第一件事是根据您使用的相同架构生成 C# 类。你可以这样做:

    1. 安装 avrogen 工具: dotnet tool install --global Apache.Avro.Tools
    2. 生成类:avrogen -s user_schema.avsc .

    然后您将获得带有类实现的User.cs。您需要做的就是配置 .NET Kafka 客户端并使用消息:

    var schemaRegistryConfig = new SchemaRegistryConfig
    {
        Url = "schemaRegistryUrl"
    };
    
    var consumerConfig = new ConsumerConfig
    {
        BootstrapServers = "bootstrapServers",
        GroupId = "group"
    };
    
    using var schemaRegistry = new CachedSchemaRegistryClient(schemaRegistryConfig);
    using var consumer = new ConsumerBuilder<string, User>(consumerConfig)
        .SetValueDeserializer(new AvroDeserializer<User>(schemaRegistry).AsSyncOverAsync())
        .Build();
    
    consumer.Subscribe(topicName);
    
    var consumeResult = consumer.Consume(cts.Token);
    

    您可以查看this example 了解更多信息。

    请注意,您不能使用您在问题中提供的 User 类,因为对类结构有一些要求。因此,您应该使用由 Avro 架构中的工具生成的那个。

    【讨论】:

    • 感谢您的回复!命名空间是否必须在 .NET 和 Java 应用程序中完全匹配?
    • @Philban 是的,模型类的命名空间应该跨语言匹配。您应该使用相同的 avro 模式在 Java 和 .NET 中生成类,并且您不应该手动编辑这些生成的文件。
    • 非常感谢您的宝贵时间和帮助!
    • 没问题。请记住,如果您想更改架构,请不要忘记在架构注册表中进行更新。
    • 谢谢!我会调查一下,因为我在进行轻微修改时已经遇到了问题!
    猜你喜欢
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 2017-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-22
    相关资源
    最近更新 更多