У нас проблемы с передачей по сети при использовании Spring Boot 2.0, Webflux 5.0.7 и Netty 4.1.25.Мы хотим передать 100000 элементов, сериализованных в формате JSON (примерно 10 МБ сетевого трафика), одному клиенту.
Производительность передачи по сети резко отличается между NIO и традиционным IO.Результаты теста приведены ниже:
Start reading 100000 from server in 5 iterations
Avg HTTP 283 ms
Avg stream 8130 ms
На данный момент количество запросов в секунду не является проблемой , но скорость передачи по сети равна.Мы читали, что с точки зрения скорости сети NIO может быть примерно на 30% медленнее, но 1 / 30x является избыточным.
При выборке на стороне клиента и сервера мы заметили, что причина в основном в реализации на стороне сервера.Из скриншота ниже видно, что большую часть времени сервер тратит на методы select()
и doWrite()
.
Сам код конечной точки:
@RestController
@RequestMapping(produces = {APPLICATION_JSON_VALUE, APPLICATION_STREAM_JSON_VALUE})
@Validated
public class StreamingController {
private static final Logger log = LoggerFactory.getLogger(StreamingController.class);
@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);
}
Мы используем конфигурацию Spring Boot для Netty, и мы подозреваем, что по умолчанию Netty настроена неправильно.Мы ищем вашей помощи.Я добавлю любые другие детали по вашему запросу.
Upd: Цель состоит в том, чтобы прочитать весь ответ в пакетном режиме, чтобы избежать помещения всего ответа в память, поскольку ожидаемые объемы данных огромны (параГб).Допустимо использовать пакет данных на стороне клиента вместо одного элемента.