Middle+
99
Er is een backend, er is een frontend. Standaard stack: Java, Spring, React, Postgres. Taak: Ontwerp een REST-endpoint dat gegevens uit 3 bronnen moet halen en aan de UI moet leveren, terwijl de maximale doorvoer en minimale responstijd worden gegarandeerd (maximale/minimale criteria op basis van onze specifieke voorwaarden, omdat er in feite geen magische oplossing is en we een compromis moeten vinden). Het is bekend dat de verwachte piek RPS voor deze REST-endpoint 200 zal zijn. Bekende details over de bronnen: 1. bron - onze database, query duurt ongeveer 3 seconden. 2. bron - een gerelateerde REST-service, degradeert tot 2 minuten bij 100 RPS, reageert in normale modus in 5 seconden. We kunnen het gedrag van deze bron niet wijzigen. 3. bron - een andere gerelateerde REST-service, reageert willekeurig met 503-fouten (geen duidelijk patroon), in normale modus reageert in 10 seconden. We kunnen het gedrag van deze bron niet wijzigen.
Bedrijven waar gevraagd werd
Antwoord van AI
sobes.tech AI
Для проектирования REST-эндпоинта с тремя источниками данных и требованиями по максимальной пропускной способности и минимальному времени отклика, учитывая особенности источников, можно предложить следующий подход:
-
Асинхронный вызов источников:
- Запрос к базе (3 сек) можно выполнять параллельно с вызовами к REST-сервисам.
- Вызовы к двум REST-сервисам также выполнять параллельно.
-
Кэширование:
- Для второго источника, который деградирует при высокой нагрузке, стоит использовать кэширование результатов, чтобы снизить количество запросов к нему.
- Кэш можно обновлять с определённой периодичностью или по событию.
-
Обработка ошибок и таймауты:
- Для третьего источника, который может отдавать 503, нужно реализовать механизм повторных попыток с экспоненциальной задержкой и fallback (например, возвращать последние успешные данные или заглушку).
- Установить разумные таймауты для всех запросов, чтобы не блокировать ответ UI.
-
Пул потоков и ограничение параллелизма:
- Для REST-сервисов использовать пул потоков с ограничением количества одновременных запросов, чтобы не перегружать внешние сервисы.
-
Сбор и агрегация данных:
- После получения данных из всех источников агрегировать их и отдать UI.
-
Мониторинг и метрики:
- Внедрить мониторинг времени отклика и ошибок, чтобы оперативно реагировать на деградацию.
Пример упрощённого кода на Java с использованием CompletableFuture:
CompletableFuture<Data1> dbFuture = CompletableFuture.supplyAsync(() -> fetchFromDb());
CompletableFuture<Data2> service2Future = CompletableFuture.supplyAsync(() -> fetchFromService2WithCache());
CompletableFuture<Data3> service3Future = CompletableFuture.supplyAsync(() -> fetchFromService3WithRetry());
CompletableFuture.allOf(dbFuture, service2Future, service3Future).join();
Data1 d1 = dbFuture.get();
Data2 d2 = service2Future.get();
Data3 d3 = service3Future.get();
Response response = aggregate(d1, d2, d3);
return response;
Таким образом, достигается баланс между временем отклика и нагрузкой на внешние сервисы, а также обеспечивается устойчивость к ошибкам.