Sobes.tech
Middle+
101

Mūsu paredzētais maksimālais RPS šim REST galapunktam ir 200: 1. avots - mūsu datu bāze, vaicājums ilgst apmēram 3 sekundes. 2. avots - saistīts REST pakalpojums, degradējas līdz 2 minūtēm pie 100 RPS, normālā režīmā atbild 5 sekundēs. Mēs nevaram mainīt šī avota uzvedību. 3. avots - cits saistīts REST pakalpojums, nejauši atgriež 503 kļūdas (bez skaidra modeļa), normālā režīmā atbild 10 sekundēs. Mēs nevaram mainīt šī avota uzvedību.

Uzņēmumi, kur jautāja
СБЕРСБЕР

Atbilde no AI

sobes.tech AI

Для проектирования REST-эндпоинта с тремя источниками данных и требованиями по максимальной пропускной способности и минимальному времени отклика, учитывая особенности источников, можно предложить следующий подход:

  1. Асинхронный вызов источников:

    • Запрос к базе (3 сек) можно выполнять параллельно с вызовами к REST-сервисам.
    • Вызовы к двум REST-сервисам также выполнять параллельно.
  2. Кэширование:

    • Для второго источника, который деградирует при высокой нагрузке, стоит использовать кэширование результатов, чтобы снизить количество запросов к нему.
    • Кэш можно обновлять с определённой периодичностью или по событию.
  3. Обработка ошибок и таймауты:

    • Для третьего источника, который может отдавать 503, нужно реализовать механизм повторных попыток с экспоненциальной задержкой и fallback (например, возвращать последние успешные данные или заглушку).
    • Установить разумные таймауты для всех запросов, чтобы не блокировать ответ UI.
  4. Пул потоков и ограничение параллелизма:

    • Для REST-сервисов использовать пул потоков с ограничением количества одновременных запросов, чтобы не перегружать внешние сервисы.
  5. Сбор и агрегация данных:

    • После получения данных из всех источников агрегировать их и отдать UI.
  6. Мониторинг и метрики:

    • Внедрить мониторинг времени отклика и ошибок, чтобы оперативно реагировать на деградацию.

Пример упрощённого кода на 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;

Таким образом, достигается баланс между временем отклика и нагрузкой на внешние сервисы, а также обеспечивается устойчивость к ошибкам.