gpt4 book ai didi

java - 两个 Quarkus 服务之间的非阻塞数据流(Vert.x with Mutiny in Java)

转载 作者:行者123 更新时间:2023-12-05 02:50:31 27 4
gpt4 key购买 nike

更新!

在解决了一些与仍然是关于服务之间的非阻塞流的主要问题无关的问题之后,我修复了示例代码中的小错误。

背景信息:

我正在 Quarkus 下移植一个 Spring WebFlux 服务。该服务对多个庞大的数据集进行长时间搜索,并在部分结果可用时在 Flux(文本/事件流)中返回它们。

问题:

现在我正在尝试在 Quarkus 下将 Mutiny Multi 与 Vert.x 结合使用,但无法弄清楚消费者服务如何在不阻塞的情况下接收此流。

在所有示例中,消费者要么是一个 JS 前端页面,要么生产者的内容类型是 application/json,这似乎是 black,直到 Multi 完成才将其发送到一个 JSON 对象中(这在我的应用程序中没有意义)。

问题:

  1. 如何使用 Mutiny 风格的 Vert.x WebClient 接收文本/事件流?
  2. 如果问题是 WebClient 无法接收连续流:在两个 Quarkus 服务之间传输数据的标准方法是什么?

这是一个简化的例子

测试实体

public class SearchResult implements Serializable {

private String content;

public SearchResult(String content) {
this.content = content;
}


//.. toString, getters and setters

}

Producer 1. 简单无限流 -> 挂起

@GET
@Path("/search")
@Produces(MediaType.SERVER_SENT_EVENTS)
@SseElementType(MediaType.APPLICATION_JSON)
public Multi<SearchResult> getResults() {
return Multi.createFrom().ticks().every(Duration.ofSeconds(2) .onItem().transform(n -> new SearchResult(n.toString()));
}

Producer 2. 使用 Vertx Paths 无限流 -> 挂起

@Route(path = "/routed", methods = HttpMethod.GET)
public Multi<SearchResult> getSrStreamRouted(RoutingContext context) {
log.info("routed run");
return ReactiveRoutes.asEventStream(Multi.createFrom().ticks().every(Duration.ofSeconds(2))
.onItem().transform(n -> new SearchResult(n.toString()));
}

Producer 3. 简单的有限流 -> 阻塞直到完成

@GET
@Path("/search")
@Produces(MediaType.SERVER_SENT_EVENTS)
@SseElementType(MediaType.APPLICATION_JSON)
public Multi<SearchResult> getResults() {
return Multi.createFrom().ticks().every(Duration.ofSeconds(2))
.transform().byTakingFirstItems(5)
.onItem().transform(n -> new SearchResult(n.toString()));
}

消费者:

在生产者和消费者方面尝试了多种不同的解决方案,但在每种情况下,流都会阻塞,直到完成或无限期挂起,而不会为无限流传输数据。我用 httpie 得到了相同的结果。这是最新的迭代:

WebClientOptions webClientOptions = new WebClientOptions().setDefaultHost("localhost").setDefaultPort(8182);
WebClient client = WebClient.create(vertx, webClientOptions);

client.get("/string")
.send()
.onFailure().invoke(resp -> log.error("error: " + resp))
.onItem().invoke(resp -> log.info("result: " + resp.statusCode()))
.toMulti()
.subscribe().with(r -> log.info(String.format("Subscribe: code:%d body:%s",r.statusCode(), r.bodyAsString())));

最佳答案

Vert.x Web 客户端不能与 SSE 一起工作(没有配置)。来自 https://vertx.io/docs/vertx-web-client/java/ :

Responses are fully buffered, use BodyCodec.pipe to pipe the response to a write stream

它等待直到响应完成。您可以使用 raw Vert.x HTTP 客户端或使用 pipe 编解码器。示例在 https://vertx.io/docs/vertx-web-client/java/#_decoding_responses 上给出.

或者,您可以使用 SSE 客户端,例如: https://github.com/quarkusio/quarkus-quickstarts/blob/master/kafka-quickstart/src/test/java/org/acme/kafka/PriceResourceTest.java#L27-L34

关于java - 两个 Quarkus 服务之间的非阻塞数据流(Vert.x with Mutiny in Java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63649235/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com