Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache kafka 如何在卡夫卡流中动态处理并发送到不同的主题_Apache Kafka_Apache Kafka Streams_Spring Kafka - Fatal编程技术网

Apache kafka 如何在卡夫卡流中动态处理并发送到不同的主题

Apache kafka 如何在卡夫卡流中动态处理并发送到不同的主题,apache-kafka,apache-kafka-streams,spring-kafka,Apache Kafka,Apache Kafka Streams,Spring Kafka,我正在创建一个流处理应用程序。它应该创建一个kafka流连接。当信息到达时,我需要做以下几件事: 检查消息的类型 通过调用specificTypeProcessing服务来处理消息 最后是根据消息类型确定的特定主题 public java.util.function.Consumer<KStream<String, String>> process() { String topic; return input -> inpu

我正在创建一个流处理应用程序。它应该创建一个kafka流连接。当信息到达时,我需要做以下几件事:

  • 检查消息的类型
  • 通过调用specificTypeProcessing服务来处理消息
  • 最后是根据消息类型确定的特定主题

    public java.util.function.Consumer<KStream<String, String>> process() {
        String topic;
        return input ->
                input.map((key, value) -> {
                    //check type and ask object from factory
                    try {
                        JSONObject msg = Util.getObjectMapper().readValue(value, JSONObject.class);
                        String type = msg.get("type").toString();
                        if(type.equalsIgnoreCase("test")){
                            //processing started
                            msgTypeHandlerFactory
                                    .createInstance(type)
                                    .enrichAndRelay(msg);
                            System.out.println("IN");
                        }
                        else{
                            input.to("notStream");
                            System.out.println("OUT");
                        }
    
                    } catch (JsonProcessingException e) {
                        e.printStackTrace();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return KeyValue.pair(key, value);
    
                })
                .to("output_topic");
    
    }
    
    public java.util.function.Consumer进程(){
    字符串主题;
    返回输入->
    input.map((键,值)->{
    //检查类型并向工厂询问对象
    试一试{
    JSONObject msg=Util.getObjectMapper().readValue(值,JSONObject.class);
    字符串类型=msg.get(“type”).toString();
    if(类型等信号情况(“测试”)){
    //开始处理
    msgTypeHandlerFactory
    .createInstance(类型)
    .继电器(msg);
    系统输出打印项次(“输入”);
    }
    否则{
    输入到(“notStream”);
    System.out.println(“out”);
    }
    }捕获(JsonProcessingException e){
    e、 printStackTrace();
    }捕获(例外e){
    e、 printStackTrace();
    }
    返回KeyValue.pair(键,值);
    })
    。至(“输出主题”);
    }
    
    上面代码的问题是我使用的是map函数,它使我能够使用.to()函数发送流。 我想要的是检查每个消息的类型,然后进行处理,并相应地发送到另一个流。 为此,我应该使用foreach函数,它没有给我.to()函数,所以我必须创建另一个卡夫卡制作人来完成这项工作

要求:

  • 在流函数的帮助下,在处理下一个消息之前,每个消息都应该被处理和发送,而不是使用另一个卡夫卡生产者
  • 如果实现了需求一,那么我应该能够将消息发送到根据类型动态决定的主题

  • 如果要检查类型,基本上就是过滤那些与这些类型匹配的事件

    因此,您不需要map或foreach,您最好使用
    filter(…).to(topic}

    final ObjectMapper mapper=Util.getObjectMapper();
    KStream notTestEvents=input.filter((键,值)->{
    //检查类型并向工厂询问对象
    试一试{
    JSONObject msg=mapper.readValue(value,JSONObject.class);//您可能应该改用JSONDeserializer,它可以为您实现这一点
    字符串类型=msg.get(“type”).toString();
    System.out.println(“out”);
    return!type.equalsIgnoreCase(“测试”);
    }捕获(JsonProcessingException e){
    e、 printStackTrace();
    }捕获(例外e){
    e、 printStackTrace();
    }
    );
    notTestEvents.to(“notStream”);
    
    另一种选择是分支

    KStream<String, String>[] branches = events.branch(
        (k, v) -> { 
           return !mapper
              .readValue(value, JSONObject.class)
              .get("type").toString();
              .equalsIgnoreCase("test")
        },
        (k, v) -> true
    );
    branches[0].map(...).to("notStream");
    branches[1].map(...).to("output_topic");
    
    KStream[]branchs=events.branch(
    (k,v)->{
    返回!地图绘制者
    .readValue(值,JSONObject.class)
    .get(“type”).toString();
    .equalsIgnoreCase(“测试”)
    },
    (k,v)->正确
    );
    分支[0]。映射(…)。到(“notStream”);
    分支[1]。映射(…)。到(“输出主题”);
    
  • 在流函数的帮助下,在处理下一个消息之前,每个消息都应该被处理和发送,而不是使用另一个卡夫卡生产者
  • 默认情况下,这种情况无论如何都会发生

  • 如果实现了需求一,那么我应该能够将消息发送到根据类型动态决定的主题
  • 首先,为了简化根据事件类型处理事件的步骤,请查看
    branch()
    branch()
    函数允许您提供固定数量的谓词,将消息路由到不同的子流中。然后您可以独立处理这些子流,例如使用
    map()
    函数。最后,您可以使用
    to()
    将每个子流发送到单独的主题

    KStream[]branchs=events.branch(
    (id,event)->event.getTransactionValue()>=欺诈限额,
    (id,event)->event.getTransactionValue();
    分支[0]。映射(…)。到(可疑的TransactionStopicName);
    分支[1]。映射(…)。到(validatedTransactionsTopicName);
    
    您还可以在
    to()
    中根据事件负载中的任何内容做出真正的动态路由决策。这里,输出主题的名称来自事件数据

    myStream.to(
    (eventId、event、record)->“主题前缀-”+event.methodOfYourEventLikeGetTypeName()
    );
    

    此外,如果动态路由决策需要事件中不直接可用的信息,则您可以选择使用路由相关信息动态丰富原始事件(例如,通过将原始事件流与具有路由相关信息的表连接),然后通过
    to()执行动态路由
    。有关详细信息,请参阅。

    筛选器解决了选择类型的问题。但是map函数是一次处理一条记录并将其发送到输出流,还是逐个处理所有记录,然后将所有记录一次发送到输出流?我将使用它作为输入流->按类型筛选->。map函数->。to()fumctionmap和filter函数都是一个接一个的。您需要一个groupBy或其他聚合来将数据收集到更大的消息中