Spring планировщик для нескольких задачJAVA

Программисты JAVA общаются здесь
Anonymous
Spring планировщик для нескольких задач

Сообщение Anonymous »

Недавно весной я начал больше узнавать о планировщике, поэтому хотел создать небольшой проект, чтобы в будущем получить больше опыта для собеседований, но сейчас я застрял в проблеме производительности. Позвольте мне описать, что я хочу сделать.
Я хочу воссоздать весеннюю веб-игру, такую ​​как Tribal Wars/Ikariam/Travian. Я использую Spring + PG в качестве бэкэнда. Я выполнил аутентификацию и другие задачи, но сейчас работаю над выполнением задач в установленное время. У меня есть таблицы заказов в PG (buildingOrder, troopOrder, TrainingOrder), у которых есть дата начала и окончания. Моя текущая логика такова:

Если order.endDate>сейчас + 10 минут -> записать в БД

иначе очередь.add(order) + записать в БД
Таким образом, у меня есть заказы, которые выполняются в очереди.

Код: Выделить всё

// Only near‑future orders live here, sorted by endDate
private final PriorityBlockingQueue queue =
new PriorityBlockingQueue(256, Comparator.comparing(BuildingOrder::getEndDate));
Таким образом, мне не нужно заглядывать в базу данных каждую секунду, а только в очереди. Также каждые 10 минут я загружаю в очередь новые заказы (второе задание планировщика).
Это моя основная галочка планировщика

Код: Выделить всё

@Scheduled(cron = "0/1 * * * * *")
public void tick() {
long tickStart = System.currentTimeMillis();
LocalDateTime now = LocalDateTime.now().plusSeconds(1);

List ready = new java.util.ArrayList();

synchronized (queue) {
while (true) {
BuildingOrder order = queue.peek();
if (order == null) {
break;
}
if (order.getEndDate().isAfter(now)) {
break;
}
ready.add(queue.poll());
}
}

if (ready.isEmpty()) {
long tickEnd = System.currentTimeMillis();
log.info("TICK done (no ready orders) durationMs={}", tickEnd - tickStart);
return;
}

log.info("TICK dispatching {} ready orders", ready.size());

for (BuildingOrder order : ready) {
processOrderAsync(order.getId());
}

long tickEnd = System.currentTimeMillis();
log.info("TICK done durationMs={} dispatched={}", tickEnd - tickStart, ready.size());
}
У меня также есть рабочие процессы, которые настраиваются в зависимости от размера запроса. Эта установка работает нормально, но только для 30-50 заданий в секунду. ProcessOrderAsync — это функция, с помощью которой я получаю данные из БД, обновляю ресурсы (goldProduction, StoneProduction, ...) и Village maxPopulation и т. д.
Вопрос
Как я могу заставить планировщик обрабатывать более 1000 заданий в секунду?
Это то, что я придумал с небольшой помощью ИИ, но теперь мне нужна помощь с точки зрения архитектора. Я знаю, что можно внести некоторую корректировку в логику кода, и я все еще исправляю ее, чтобы она была читабельной и чтобы у меня было как можно меньше операций выбора/обновления в базе данных, но все же, когда я запускал 1000 задач, которые должны были выполняться за одну секунду, некоторые из них выполнялись быстро, а некоторые - целых 6-7 секунд.

У меня нет какой-либо специальной конфигурации для БД или потоков, единственное, что я настроил, это то, что я могу иметь до 32 рабочих процессов (query.size>500)

Вернуться в «JAVA»