ОК, так что мы на самом деле говорим об асинхронных вызовах, реализованных с использованием механизма Spring @async
.
Согласно https://www.baeldung.com/spring-async:
Проще говоря - аннотирование метода компонента с помощью @Async
заставит его выполнить в отдельном потоке ; то есть вызывающая сторона не будет ждать завершения вызванного метода.
и
По умолчанию Spring использует SimpleAsyncTaskExecutor
для фактического выполнения этих методов асинхронно.
Глядя на javadocs для SimpleAsyncTaskExecutor
, мы видим:
Реализация TaskExecutor, которая запускает новый поток для каждой задачи, выполняя его асинхронно.
Поддерживает ограничение параллельных потоков через свойство компонента "concurrencyLimit". По умолчанию количество одновременных потоков не ограничено.
ПРИМЕЧАНИЕ. В этой реализации не используются потоки! Вместо этого рассмотрим реализацию TaskExecutor с пулом потоков, в частности, для выполнения большого количества краткосрочных задач.
Итак, из этого мы можем сделать вывод (если вы не выполнили какую-либо дополнительную настройку, о которой вы не упомянули):
- Каждый из ваших асинхронных вызовов использует отдельный поток.
- Нет пула потоков для повторного использования потоков.
- Механизм не ограничивает количество создаваемых потоков.
Создание потока стоит дорого, и каждый поток потребляет значительный объем памяти. Так что я ожидаю, что происходит то, что вы перегружаете JVM чрезмерным количеством потоков, и это приводит к остановке. (Либо из-за гибели спирали ГХ, перегрузки виртуальной памяти или, возможно, перегрузки сети из-за попытки сделать слишком много загрузок одновременно.)
По сути, этот наивный подход не будет масштабироваться. Лучше было бы использовать ExecutorService с ограниченным пулом потоков и отправлять запросы на загрузку в виде задач. Служба executor поставит задачи в очередь и отправит их в свой пул рабочих потоков. Вы должны настроить размер пула потоков так, чтобы он не перегружал вашу локальную память / вычисления, ваше сетевое соединение ... и удаленные серверы, которые вы НАРУШАЕТЕ при параллельных загрузках.
Также возможно, что удаленные серверы ограничивают ваши загрузки ... потому что ваши массово параллельные загрузки выглядят как атака DOS.