Восстановление из OOM при выделении DirectByteBuffer на веб-сервере WebFlux

#spring-webflux #project-reactor #reactor-netty

Вопрос:

Я не уверен, имеет ли это смысл, поэтому, пожалуйста, прокомментируйте, если мне нужно предоставить дополнительную информацию:

Мой веб-сервер используется для загрузки файлов (получает файлы в виде составных/форм-данных и загружает их в другую службу). Используя WebFlux, контроллер определяет аргумент как a @RequestPart(name = "payload") final Part payload , который обертывает заголовок и поток.

Реактор / Нетти использует DirectByteBuffers для размещения полезной нагрузки. Если обработчик запроса не сможет получить достаточно прямой памяти для обработки запроса, он завершится ошибкой в OOM и вернет 500. Так что это нормально / ожидаемо.

Однако, что должно произойти после этого?

Я запускаю нагрузочные тесты, отправляя одновременно несколько запросов (либо много запросов с небольшими файлами, либо меньше запросов с большими файлами). Как только я получу первые 500 из-за ООМ, система станет нестабильной. Некоторые запросы будут проходить, а другие завершатся сбоем с помощью OOM (даже запросы с очень небольшой полезной нагрузкой могут завершиться сбоем). Такое поведение заставляет меня полагать, что выделенные объединенные буферы не распределяются между каналами ввода-вывода? Однако это кажется странным, это делает систему очень легкой для DDOS-атак?

Из тестов, которые я провел, я получаю такое же поведение при использовании буферов данных без пула, хотя и по другой причине. Я вижу, что память при этом не jcmd <PID> VM.native_memory распределяется, но они не загружаются в ОС в соответствии с метриками и htop. Например, зарезервированная память, показанная jcmd, снова уменьшается, но htop по-прежнему сообщает о прежнем высоком объеме, и в конечном итоге он увеличивается.

Итак, вопрос : Это полностью ожидаемо или я где-то пропустил значение конфигурации?

Настройка : Весенняя загрузка 2.5.5 на openjdk11:конфигурация jdk-11.0.10_9 Netty : -Dio.netty.allocator.type=pooled -Dio.netty.leakDetectionLevel=paranoid -Djdk.nio.maxCachedBufferSize=262144 -XX:MaxDirectMemorySize=1g -Dio.netty.maxDirectMemory=0