仅在收到某些事件时才使用spring从kafka主题中消费

时间:2019-06-04 18:50:45

标签: java spring-boot apache-kafka spring-kafka

我在春季启动应用程序中创建了一个kafka使用者,它监听一个主题- my_topic ,并在读取事件 my_event 时执行一些操作。现在我正在这样做:

@KafkaListener(topics = "my_topic",
          containerFactory = "my_kafka_container_factory")
public void handleMyKafkaEvents(String eventJson) {
    MyDTO my_dto = gson.fromJson(eventJson, MyDTO.class);
    String event_type = my_dto.getEventType();
    if (event_type != null && event_type.equals("my_event")) {
        // do something with my_dto
    }
}

// dto object
public class MyDTO {
    private String status;

    private String eventType;

    private String propName;

    // some other parameters

    // getters and setters
}

我的kafka主题中的对象外观示例:

{
  "eventType": "my_event",
  "propName": "prop_value",
  "status": "DONE",
  //some_other_key_value_pairs_required_in_my_DTO
  //some_other_key_value_pairs_not_required_in_my_DTO
}

由于我的监听器正在监听所有推送到kafka主题的数据,因此我必须在读取每条记录后添加一个条件,即如果我需要它的eventType,那么我将对其执行一些操作。

到目前为止,该功能正在运行。由于还会有其他数据推送到其上,而这些数据的eventType不是我所需要的,因此这些数据将被忽略,但只有在读取它们之后,因为我不知道如何基于此eventType进行过滤。

所以我的问题是,当推送到kafka主题的事件数量突然增加时,不仅是我的eventType,而且还有其他事件,这会影响我的服务性能吗?

我在这里可以改善什么,以便其他eventType被忽略,我的侦听器甚至不必了解它们。

1 个答案:

答案 0 :(得分:2)

某些方法可能适合您的用例,但可能会有所帮助:

  • 在密钥中包含掩码

在kafka key中包含一些特定的代码,因此您无需阅读payload即可知道是否必须处理该消息。

一个愚蠢的例子:

key      payload
-----------------
10_ev  xxx
08_ev  yyy
...

在这个简单的示例中,前两个数字确定事件的类型。每个消费者组都分配有一个要处理的特定事件,而丢弃其他事件。 当心!为此,您需要启动与事件类型一样多的使用者组,这样就不会丢失消息,或者将特定范围的事件分配给所有使用者(例如,使用者0处理0-9之间的事件类型,从10-19开始的消费者1,...)

  • 根据事件进行分区

您可以告诉生产者(应该知道他正在生产的事件类型的人)对消息进行分区(将消息发送到特定的分区到主题中),例如,您知道所有事件类型为0 的对象位于分区0 上,并且记住这一点。

无论如何,事件类型过多可能会降低其选择范围,使其可用。您可以根据范围(事件类型0到0在分区0上,等等)进行分区,但是,也许那里有些麻烦。

  • 根据事件类型发送到不同的主题

好吧,这肯定是最简单的一种,但是如果您有很多事件类型(像数千个,... ),则可能是个问题。 :)

希望有帮助。关于您的用例here,有一些有趣的信息。