【发布时间】:2019-03-21 01:55:17
【问题描述】:
我们在使用 Spring Boot 2.0、Webflux 5.0.7 和 Netty 4.1.25 时遇到网络传输问题。我们希望将 100000 个序列化为 JSON(大约 10Mb 的网络流量)的项目传输到 1 个客户端。
NIO 和传统 IO 的网络传输性能有很大不同。 测试结果如下:
Start reading 100000 from server in 5 iterations
Avg HTTP 283 ms
Avg stream 8130 ms
目前每秒的请求数不是问题,但网络传输速度才是问题。我们已经了解到 NIO 的网络速度可能会慢 30% 左右,但 1/30 倍是多余的。
在客户端和服务器端进行采样时,我们观察到原因主要在于服务器端实现。从下面的截图可以看出,服务器大部分时间都花在了select() 和doWrite() 方法上。
端点代码本身:
@RestController
@RequestMapping(produces = {APPLICATION_JSON_VALUE, APPLICATION_STREAM_JSON_VALUE})
@Validated
public class StreamingController {
@GetMapping("/instruments/{eodDate}")
public Flux<TestItem> getInstruments(
@PathVariable @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate eodDate,
@RequestParam(required = false) Instant asOfTimestamp) {
//Generate test data in memory
List<TestItem> collect = IntStream.range(0, 100000)
.mapToObj(i -> new TestItem.Builder().build())
.collect(Collectors.toList());
return Flux.fromIterable(collect);
}
}
我们正在为 Netty 使用 Spring Boot 配置,我们怀疑默认情况下 Netty 配置错误。 我们正在寻求您的帮助。我会根据您的要求添加任何其他详细信息。
更新: 目标是批量读取整个响应以避免将所有响应放入内存,因为预期的数据量很大(几 Gb)。在客户端消费一批数据而不是一个元素是可以接受的。
【问题讨论】:
-
我不明白。您将该代码与什么进行比较?内存中的
Stream?文件输入/输出?原始套接字 I/O? -
@StephenC 在客户端,我首先使用常规 REST HTTP 访问此端点,然后使用 Webflux 客户端并比较下载内容所需的时间。 Spring 处理头文件“application/json”与“application/stream+json”的差异,对于 HTTP 调用,将返回的
Flux转换为Collection。所以我基本上是在比较网速。 -
请详细说明 - 您能否在此处粘贴更多关于您正在比较的内容、您正在制作的 HTTP 请求/响应标头的详细信息?
-
@BrianClozel 我正在比较 Swagger 中两种方法的响应时间。为了测试 REST HTTP,我发送“application/json”标头,为了测试 Webflux,我发送“application/stream+json”。我在浏览器中检查“网络”选项卡以避免 Json 反序列化的时间。
标签: java spring spring-boot netty spring-webflux