Противодавление микронавта

Мы ищем лучший способ ограничить количество одновременных подключений, принимаемых конечной точкой HTTP, доступной с помощью Micronaut 2.0.1. Конечная точка принимает файлы изображений, записывает их на диск и создает эскизы. При слишком большом количестве запросов нам не хватает памяти.

На данный момент мы обнаружили настройки для пулов потоков Netty . Однако мы сомневаемся, могут ли они позволить нам установить определенный лимит. Кажется, они больше связаны с пулами потоков цикла событий Netty?

Есть ли хорошо зарекомендовавший себя способ реализовать подобное противодавление с помощью Micronaut и Netty?


person jjarzynski    schedule 14.10.2020    source источник
comment
Привет, я не думаю, что микронавт и нетти помогут тебе в таком противодействии. Событие: если вы ограничите пул потоков, у вас либо будет недостаточно памяти из-за очереди, либо тот, который вызывает ваш API, будет иметь ошибку. Вам следует попробовать использовать очередь, такую ​​как Kafka или RabbitMq, для хранения изображений и использования их с большим контролем.   -  person Anorgar    schedule 14.10.2020
comment
Я нормально отправляю вызывающим абонентам сообщения об ошибках, когда я перегружен   -  person jjarzynski    schedule 14.10.2020
comment
Затем вы должны попытаться найти конфигурацию с помощью нагрузочных тестов, чтобы убедиться, что вызывающий абонент получит сообщение об ошибке до того, как ваше приложение выйдет из строя. Вся доступная конфигурация для сервера micronaut и netty находится здесь: docs.micronaut.io/latest/guide/ Вы должны использовать реактивный контроллер Micronaut для невозможности управления потоками netty. Извините, я больше не смогу.   -  person Anorgar    schedule 14.10.2020


Ответы (1)


Нет готовой конфигурации, которая принудительно ограничивает параллелизм, как вы того хотите. Вероятно, вы захотите реализовать HttpServletFilter, который отслеживает количество выполняемых в настоящее время запросов и отвечает статусом 429 Too Many Requests, если количество превышает настроенный предел. Что-то похожее на приведенный ниже код должно работать (ПРИМЕЧАНИЕ: не проверено)

​@Override
​public Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request, ServerFilterChain chain) {
       ​return Flowable.fromCallable(() -> atomicRequestCounter.incrementAndGet())
                      .subscribeOn(Schedulers.computation())
                      .flatMap(numConcurrentRequests -> {
                          if (numConcurrentRequests > MAX_ALLOWED_CONCURRENCY) {
                              return Flowable.just(HttpResponse.status(HttpStatus.TOO_MANY_REQUESTS));
                          } else {
                              return chain.proceed(request);
                          }
                       })
                       ​.doOnNext(res -> atomicRequestCounter.decrementAndGet());
}

Если вы действительно хотите подключить это к слою Netty, взгляните на ChannelPipelineCustomizer < / а>. Вы можете применить тот же принцип, что и выше, и добавить обработчик в конвейер, который отслеживает одновременные соединения. Обратите внимание, что преимущество метода на основе фильтра заключается в том, что он позволяет вам устанавливать ограничения для определенных URI / ресурсов, тогда как если вы применяете на уровне Netty, это влияет на все ваше приложение.

person spinlok    schedule 20.10.2020