Я хочу воссоздать весеннюю веб-игру, такую как 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));
Это моя основная галочка планировщика
Код: Выделить всё
@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());
}
Вопрос
Как я могу заставить планировщик обрабатывать более 1000 заданий в секунду?
Это то, что я придумал с небольшой помощью ИИ, но теперь мне нужна помощь с точки зрения архитектора. Я знаю, что можно внести некоторую корректировку в логику кода, и я все еще исправляю ее, чтобы она была читабельной и чтобы у меня было как можно меньше операций выбора/обновления в базе данных, но все же, когда я запускал 1000 задач, которые должны были выполняться за одну секунду, некоторые из них выполнялись быстро, а некоторые - целых 6-7 секунд.
У меня нет какой-либо специальной конфигурации для БД или потоков, единственное, что я настроил, это то, что я могу иметь до 32 рабочих процессов (query.size>500)