Sobes.tech
Senior

Կան բեկենդ, կա օգտագործողի ինտերֆեյս։ Տեխնոլոգիական շերտը ստանդարտ է՝ Java, Spring, React, Postgres։ Առաքելություն՝ նախագծել REST վերջնակետ, որը պետք է վերցնի տվյալներ 3 աղբյուրից և վերադարձնի UI-ին, ապահովելով հնարավորինս բարձր անցանելիություն և նվազագույն պատասխան ժամանակ (максимալ/մինիմ չափանիշներ՝ ըստ մեր հատուկ պայմանների, քանի որ հիմնականում չկա հրաշք լուծում և անհրաժեշտ է գտնել փոխզիջում): Նախապես հայտնի է, որ այս վերջնակետի սպասվող գագաթ RPS-ը կլինի 200: Աղբյուրների մասին մանրամասներ՝ 1. Աղբյուր՝ մեր տվյալների բազա, հարցումը մոտ 15 վայրկյան է տևում: 2. Աղբյուր՝ կապված REST ծառայություն, նվազում է մինչև 2 րոպե՝ 100 RPS-ի դեպքում, նորմալ ռեժիմում պատասխանատու է 5 վայրկյանում։ Այս աղբյուրի վարքագիծը չենք կարող փոխել: 3. Աղբյուր՝ կապված REST ծառայություն, պատահականորեն (չի հաջողվել պարզել հատուկ ձևաչափեր) պատասխանատու է 503 սխալներով, նորմալ ռեժիմում պատասխանատու է 10 վայրկյանում։ Այս աղբյուրի վարքագիծը չենք կարող փոխել։

sobes.tech AI

Պատասխան AI-ից

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

  1. Асинхронный параллельный запрос к источникам:

    • Запросы к базе и двум REST-сервисам выполняются параллельно, чтобы минимизировать общее время ожидания.
  2. Кеширование:

    • Для источника с долгим запросом к базе (15 сек) стоит реализовать кеширование результатов с разумным TTL, чтобы снизить нагрузку при пиковых запросах.
  3. Таймауты и fallback:

    • Для второго источника, который деградирует при высокой нагрузке, установить таймауты (например, 5-7 сек) и использовать кеш или возвращать частичные данные, если сервис не отвечает.
    • Для третьего источника, который иногда возвращает 503, реализовать повторные попытки с экспоненциальной задержкой и fallback на кеш или дефолтные данные.
  4. Реактивное программирование:

    • Использовать Spring WebFlux или CompletableFuture для неблокирующего выполнения запросов и объединения результатов.
  5. Агрегация и отдача данных:

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

    • Внедрить circuit breaker (например, Resilience4j) для защиты от деградации смежных сервисов.
    • Ограничить количество одновременных запросов к проблемным источникам.

Пример использования CompletableFuture для параллельного запроса:

CompletableFuture<Data1> future1 = CompletableFuture.supplyAsync(() -> fetchFromDb());
CompletableFuture<Data2> future2 = CompletableFuture.supplyAsync(() -> fetchFromService2());
CompletableFuture<Data3> future3 = CompletableFuture.supplyAsync(() -> fetchFromService3());

CompletableFuture.allOf(future1, future2, future3).join();

// Обработка результатов с учетом ошибок и таймаутов
Data1 d1 = future1.getNow(null);
Data2 d2 = future2.getNow(null);
Data3 d3 = future3.getNow(null);

// Формируем ответ
return aggregate(d1, d2, d3);

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