【发布时间】:2020-07-06 13:57:45
【问题描述】:
Spring Boot申请:
@RestController 接收以下有效负载:
{
"cartoon": "The Little Mermaid",
"characterNames": ["Ariel", "Prince Eric", "Sebastian", "Flounder"]
}
我需要按如下方式处理:
- 获取每个角色名称的唯一 ID:对“cartoon-characters”微服务进行 HTTP 调用,该微服务按名称返回 ID
控制器接收到的转换数据: 将角色名称替换为上一步从“卡通角色”微服务接收到的适当 id。
{ "cartoon": "The Little Mermaid", "characterIds": [1, 2, 3, 4] }使用转换后的数据向“cartoon-db”微服务发送 HTTP POST 请求。
- 将来自“cartoon-db”的响应映射到作为控制器返回值的内部表示。
我遇到的问题:
我需要使用Spring WebFlux (Mono|Flux) 和Spring Reactive WebClient 的范式Reactive Programming(非阻塞\异步处理)来实现所有这些步骤 - 但我对此的经验为零堆栈,尽可能多地阅读它,加上谷歌搜索很多,但仍然有一堆未回答的问题,例如:
第一季度。我已经配置了响应式 webClient,它向“cartoon-characters”微服务发送请求:
public Mono<Integer> getCartoonCharacterIdbyName(String characterName) {
return WebClient.builder().baseUrl("http://cartoon-characters").build()
.get()
.uri("/character/{characterName}", characterName)
.retrieve()
.bodyToMono(Integer.class);
}
如您所见,我有一个卡通人物名称列表,我需要为每个人调用 getCartoonCharacterIdbyName(String name) 方法,我不确定串联调用它的正确选项,相信正确的选项:并行执行。
写了如下方法:
public List<Integer> getCartoonCharacterIds(List<String> names) {
Flux<Integer> flux = Flux.fromStream(names.stream())
.flatMap(this::getCartoonCharacterIdbyName);
return StreamSupport.stream(flux.toIterable().spliterator(), false)
.collect(Collectors.toList());
}
但我怀疑此代码是否并行执行 WebClient,并且代码调用 flux.toIterable() 会阻塞线程,因此使用此实现我失去了非阻塞机制。
我的假设正确吗?
如何将其重写为具有并行性和非阻塞性?
第二季度。
技术上是否可以将控制器接收到的输入数据(我的意思是用 id 替换名称)转换为反应式:当我们使用 Flux<Integer> characterIds 操作时,而不是使用 characterIds 的 List<Integer> 操作时?
Q3. 是否有可能在 步骤 2 之后不仅获得转换后的 Data 对象,而且获得 Mono 可以由 步骤中的另一个 WebClient 使用3?
【问题讨论】:
-
你应该使用非阻塞的collectList操作符而不是toIterable,它给你一个Mono
- 。
标签: spring-boot reactive-programming spring-webflux reactive spring-webclient