Sobes.tech
Senior
58

Bir arka uç ve bir kullanıcı arayüzü var. Teknoloji yığını standart: Java, Spring, React, Postgres. Görev: 3 kaynaktan veri alıp UI'ye gönderen, mümkün olan en yüksek kapasite ve en düşük yanıt süresini sağlayan bir REST uç noktası tasarlamak (maks/mini kriterler, çünkü pratikte sihirli bir çözüm yok ve bir uzlaşma bulunmalı). Bu uç nokta için beklenen maksimum RPS'nin 200 olduğu biliniyor. Kaynaktaki bilinen detaylar: 1. Kaynak - bizim veritabanımız, sorgu yaklaşık 15 saniye. 2. Kaynak - ilişkili REST servisi, 100 RPS altında 2 dakikaya kadar düşer, normal modda 5 saniyede yanıt verir. Bu kaynağın davranışını değiştiremeyiz. 3. Kaynak - ilişkili REST servisi, rastgele (belirli desenler tespit edilmedi) 503 hatasıyla yanıt verir, normal modda 10 saniyede yanıt verir. Bu kaynağın davranışını değiştiremeyiz.

Sorulan şirketler
солюшин

AI'dan gelen yanıt

sobes.tech yapay zeka

Для проектирования 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);

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