Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.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
Java 卡夫卡流未填充_Java_Spring_Apache Kafka_Apache Kafka Streams - Fatal编程技术网

Java 卡夫卡流未填充

Java 卡夫卡流未填充,java,spring,apache-kafka,apache-kafka-streams,Java,Spring,Apache Kafka,Apache Kafka Streams,我有一个非常简单的Java/Spring应用程序来演示KStream功能,但不幸的是,我无法让KStream加载数据。其思想是创建一个KStream对象,并使用controllerget方法简单地检索其内容。示例代码: @RestController @RequestMapping("/resources/") public class StreamController { private KafkaStreams streams; private KStrea

我有一个非常简单的Java/Spring应用程序来演示KStream功能,但不幸的是,我无法让KStream加载数据。其思想是创建一个KStream对象,并使用controllerget方法简单地检索其内容。示例代码:

@RestController
@RequestMapping("/resources/")
public class StreamController {

   private KafkaStreams streams;
   private KStream<String, ResourceMessage> resourceStream;

   StreamController() {

      // configure streams/consumer
      Properties props = new Properties();

      // make sure stream starts from the beginning
      props.put(StreamsConfig.APPLICATION_ID_CONFIG, UUID.randomUUID().toString());
      props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");

      props.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
      props.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());
      props.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());
      props.put(StreamsConfig.STATE_DIR_CONFIG, Path.of(System.getProperty("java.io.tmpdir")).toAbsolutePath().toString());

      //create POJO serdes
      StreamsBuilder builder = new StreamsBuilder();
      Map<String, Object> serdeProps = new HashMap<>();
      Serializer<ResourceMessage> resourceSerializer = new JsonPOJOSerializer<>();
      serdeProps.put("JsonPOJOClass", ResourceMessage.class);
      resourceSerializer.configure(serdeProps, false);
      Deserializer<ResourceMessage> resourceDeserializer = new JsonPOJODeserializer<>();
      serdeProps.put("JsonPOJOClass", Resource.class);
      resourceDeserializer.configure(serdeProps, false);
      Serde<ResourceMessage> resourceSerde = Serdes.serdeFrom(resourceSerializer, resourceDeserializer);

      // create KStream with POJO serdes for value
      resourceStream = builder.stream("Resources", Consumed.with(Serdes.String(), resourceSerde));
      streams = new KafkaStreams(builder.build(), props);
      streams.start();
     }

   // GET method that enumerates KStream and returns contents
   @GetMapping(value = "/resource")
   public List<Resource> getResources() {

       List<ResourceMessage> messages = new LinkedList<ResourceMessage>();

       // problem is here - there are messages in the topic but KStream returns no values in foreach(...)
       resourceStream.foreach((key, value) -> messages.add(value));

       return messages.stream().map(m -> Resource.builder()
            .id(m.getResouceId()).resource(m.getResource()).build()).collect(Collectors.toList());
   }
}
@RestController
@请求映射(“/resources/”)
公共类流控制器{
私人卡夫卡斯特兰斯溪流;
私有KStream资源流;
StreamController(){
//配置流/消费者
Properties props=新属性();
//确保流从头开始
props.put(StreamsConfig.APPLICATION_ID_CONFIG,UUID.randomuid().toString());
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG,“最早”);
put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG,“localhost:9092”);
props.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG,Serdes.String().getClass().getName());
props.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG,Serdes.String().getClass().getName());
props.put(StreamsConfig.STATE\u DIR\u CONFIG,Path.of(System.getProperty(“java.io.tmpdir”)).toabsolutionPath().toString());
//创建pojoserdes
StreamsBuilder builder=新的StreamsBuilder();
Map serdeProps=newhashmap();
Serializer resourceSerializer=新的JsonPOJOSerializer();
serdeProps.put(“JsonPOJOClass”,ResourceMessage.class);
configure(serdeProps,false);
Deserializer resourceDeserializer=新的JsonPOJODeserializer();
serdeProps.put(“JsonPOJOClass”,Resource.class);
resourceDeserializer.configure(serdeProps,false);
Serde resourceSerde=Serdes.serdeFrom(resourceSerializer,resourceDeserializer);
//使用POJO serdes创建KStream以实现价值
resourceStream=builder.stream(“Resources”,consumered.with(Serdes.String(),resourceSerde));
streams=新的KafkaStreams(builder.build(),props);
streams.start();
}
//枚举KStream并返回内容的GET方法
@GetMapping(value=“/resource”)
公共列表getResources(){
列表消息=新建LinkedList();
//问题就在这里-主题中有消息,但KStream在foreach(…)中不返回任何值
foreach((键,值)->messages.add(值));
返回messages.stream().map(m->Resource.builder())
.id(m.getResourceId()).resource(m.getResource()).build()).collect(Collectors.toList());
}
}
问题-主题中有消息,但foreach(…)中的KStream枚举无法从中检索结果。KStream对象状态为“正在运行”,日志中没有错误

生成随机应用程序ID并将自动偏移重置设置为“最早”没有帮助。使用卡夫卡工具,我可以清楚地看到主题中的一些信息。在控制器运行时添加新消息也没有帮助。关于卡夫卡流媒体,我有什么遗漏或不明白的吗


PS我使用的是来自的POJO序列化程序和反序列化程序示例。

Kafka Streams是用于实时流处理的Kafka客户端。在您的情况下,您不需要Kafka Streams客户端(它不会工作),您需要一个简单的Kafka消费者,它轮询来自Kafka的记录并使用RESTAPI将其发送回。例如:

@RestController
@RequestMapping("/resources/")
public class StreamController {

   private KafkaStreams streams;
   private Consumer<String, ResourceMessage> consumer;

   StreamController() {

  // configure consumer properties
  Properties props = new Properties();

  // make the right properties with your Serialize and deserialiser

  props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");

  // Create the consumer using props.
  consumer = new KafkaConsumer<>(props);
  consumer.subscribe(Collections.singletonList(TOPIC));
 }

   // GET method that enumerates KStream and returns contents
   @GetMapping(value = "/resource")
   public List<Resource> getResources() {

   List<ResourceMessage> messages = new LinkedList<ResourceMessage>();

   ConsumerRecords<String, ResourceMessage> consumerRecords =
                consumer.poll(1000);
   
  
   messages = consumerRecords... // Convert the records to your custom POJO

   return messages.stream().map(m -> Resource.builder()
        .id(m.getResouceId()).resource(m.getResource()).build()).collect(Collectors.toList());
   }
}
@RestController
@请求映射(“/resources/”)
公共类流控制器{
私人卡夫卡斯特兰斯溪流;
私人消费者;
StreamController(){
//配置使用者属性
Properties props=新属性();
//使用序列化和反序列化程序生成正确的属性
put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,“localhost:9092”);
//使用道具创建消费者。
消费者=新卡夫卡消费者(道具);
consumer.subscribe(Collections.singletonList(主题));
}
//枚举KStream并返回内容的GET方法
@GetMapping(value=“/resource”)
公共列表getResources(){
列表消息=新建LinkedList();
消费记录消费记录=
消费者调查(1000);
messages=consumerRecords…//将记录转换为自定义POJO
返回messages.stream().map(m->Resource.builder())
.id(m.getResourceId()).resource(m.getResource()).build()).collect(Collectors.toList());
}
}
你可以在这里找到一个完整的例子

更新

另外,您应该知道RestControlled是请求作用域,因此为每个请求创建一个控制器实例。因此,最终API响应将一无所获。如果您想使用Kafka Streams,可以在使用Spring引导应用程序的同时,在主方法中启动它。
例如,您可以看到。

此应用程序是Spring boot应用程序?@Ismail。是的,这是一个Spring Boot应用程序。谢谢您的回答。然而,我很困惑。没有办法检查KStream或KTable来为UI构建物化视图?我读过一些文档,上面说有,我就是做不到。你能给我们提供你提到的文档的链接吗?比如书-第14章,-streams可以连接起来发送电子邮件。我认为书中描述的系统与您试图用Kafka streams做什么有很大区别。书中描述的示例是一个Kafka Streams客户端,它作为一个系统启动,根据接收到的事件实时发送电子邮件。相反,您的应用程序正在尝试创建Kafka Streams客户端,并启动该流,然后使用返回语句直接退出,因此您将一无所获。您可以找到上面的一些更新,以获得更多帮助。