Sobes.tech
Middle+
96

Има бекенд, има и фронтенд. Стандартен стек: Java, Spring, React, Postgres. Задача: Проектирайте REST крайна точка, която трябва да вземе данни от 3 източника и да ги върне на UI, като осигури максимална възможна пропускателна способност и минимално възможно време за отговор (критерии максимум/минимум според нашите конкретни условия, тъй като по същество няма магическо решение и трябва да намерим компромис). Знае се, че очакваният пик RPS за тази REST крайна точка ще бъде 200. Подробности за източниците: 1. Източник - нашата база данни, заявката отнема около 3 секунди. 2. Източник - свързан REST услуга, деградира до 2 минути при 100 RPS, в нормален режим отговаря за 5 секунди. Не можем да променим поведението на този източник. 3. Източник - друг свързан REST услуга, отговаря произволно с 503 грешки (без ясна модел), в нормален режим отговаря за 10 секунди. Не можем да променим поведението на този източник.

Компаниите бяха попитани
СБЕРСБЕР

Отговор от 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;

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