Sobes.tech
Middle+
94

Există un backend, există un frontend. Stivla standard: Java, Spring, React, Postgres. Sarcina: Proiectați un endpoint REST care trebuie să preia date din 3 surse și să le transmită către UI, asigurând capacitatea maximă posibilă și cel mai mic timp de răspuns posibil (criterii maxime/minime în funcție de condițiile noastre specifice, deoarece în esență nu există o soluție magică și trebuie să găsim un compromis). Se știe că vârful RPS așteptat pentru acest endpoint REST va fi de 200. Detalii cunoscute despre surse: 1. sursă - baza noastră de date, interogarea durează aproximativ 3 secunde. 2. sursă - un serviciu REST asociat, se degradează până la 2 minute sub 100 RPS, răspunde în mod normal în 5 secunde. Nu putem schimba comportamentul acestei surse. 3. sursă - un alt serviciu REST asociat, răspunde aleator cu erori 503 (fără un pattern clar), în mod normal răspunde în 10 secunde. Nu putem schimba comportamentul acestei surse.

Companiile au fost întrebate
СБЕРСБЕР

Răspuns de la 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;

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