У меня есть задание, которое планируется запускать каждый час, которое использует компонент Spring ThreadPoolTaskExecutor для одновременных вызовов (около 100 вызовов каждый час) к внешнему API.
@Bean
public TaskExecutor getExecutor() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(10);
threadPoolTaskExecutor.setMaxPoolSize(20);
return threadPoolTaskExecutor;
}
Теперь внешний API ограничил количество запросов и разрешает один запрос каждые 30 секунд. Перед каждым звонком мне придется ждать 30 секунд.
В этом случае я вижу, что использование ThreadPoolTaskExecutor больше не помогает. Будет ли работать ThreadPoolTaskScheduler с конфигурацией фиксированной задержки?
Как лучше всего справиться с подобным ограничением API? Пожалуйста помоги
Я использую Java 8, Spring Boot 2.0.1, если это помогает
@tmarwen Я использовал @Scheduled с выражением cron в реальном задании, которое выполняется каждый час. Могу ли я иметь одновременное расписание фиксированной задержки в ThreadPoolTaskScheduler?
@ jusemar10 Вы можете управлять расписанием в аннотации @Scheduled и оставить ThreadPoolTaskScheduler в покое.
Я предполагаю, что вам действительно нужен какой-то способ распределить вызовы, чтобы он знал, сколько времени прошло с момента последнего, и помещает их в очередь, если задачи требуют дросселирования. Хотя ничто из этого не поможет, если вы не измените свое приложение значимым образом: вам нужно изменить его, чтобы оно увеличилось со 100 вызовов в минуту до максимум 2 вызовов. Это недостижимо, если просто задушить исполнителя.
... потому что, если вы просто измените исполнителя и по-прежнему загрузите его со 100 задачами, в то время как он может обрабатывать не более 2, очередь задач будет очень быстро загрязнена (по крайней мере, 98 в минуту, если быть точным).
@ m-prokhorov Наверное, в моем сценарии подойдет очередь?




Вы могли сделать следующее.
TaskExecutor. Вы это уже сделали.Напишите метод, который вы хотите вызывать по расписанию и аннотировать с помощью @Scheduled.
@Scheduled(fixedDelay = 3600000)
void doSomething() {
}
Приведенный выше код будет запускаться каждые 1 час.
У меня уже есть такая установка. Мой вопрос в том, как ограничить вызов API, который в настоящее время запускается примерно 100 раз параллельно при каждом запуске задания.
Это всегда будет ограничивать выполнение задачи, даже если в течение последних 10 минут задачи не выполнялись.
Согласен с @ M.Prokhorov. Ваша проблема не в области инфраструктуры планирования, предоставляемой Spring. Вероятно, вам придется построить свою собственную логику. Возможно, ваша собственная пользовательская логика (или повторно используйте более низкий уровень инфраструктуры управления задачами из самой Java или Spring) для отправки задач на промежуточный процессор. Этот промежуточный процессор будет отслеживать временные метки и координировать правильную задержку между последовательными отправками.
Вы действительно знаете о решении, планировщик
ThreadPoolTaskSchedulerс 30-секундным триггером с задержкой будет работать. Почему бы вам просто не реализовать это? Есть какие-то причины?