← Назад к вопросам

Что выберешь для кэширования ответа от запроса к какой-то системе

1.8 Middle🔥 201 комментариев
#Кэширование и NoSQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Стратегии кэширования ответов от внешних систем

При работе с запросами к внешним системам важно выбрать правильную стратегию кэширования. Рассмотрю основные подходы.

1. In-Memory Cache (ConcurrentHashMap)

Для простых случаев с небольшим объемом данных хорошо подходит кэширование в памяти.

public class InMemoryCacheService<K, V> {
    private final ConcurrentHashMap<K, CacheEntry<V>> cache = new ConcurrentHashMap<>();
    private final long ttlMillis;

    public void put(K key, V value) {
        cache.put(key, new CacheEntry<>(value, System.currentTimeMillis() + ttlMillis));
    }

    public Optional<V> get(K key) {
        CacheEntry<V> entry = cache.get(key);
        if (entry == null || entry.isExpired()) {
            cache.remove(key);
            return Optional.empty();
        }
        return Optional.of(entry.value);
    }
}

Плюсы: очень быстрый доступ, простая реализация. Минусы: теряется при перезагрузке, не работает в распределённых системах.

2. Spring Cache с Caffeine

В Spring-приложениях удобно использовать аннотации с Caffeine.

@Configuration
@EnableCaching
public class CacheConfig {
    @Bean
    public CacheManager cacheManager() {
        return new CaffeineCacheManager();
    }
}

@Service
public class ExternalApiService {
    @Cacheable(value = "apiResponses", key = "#userId")
    public UserData fetchUserData(String userId) {
        return restTemplate.getForObject(
            "https://external-api.com/users/" + userId,
            UserData.class
        );
    }
}

Плюсы: декларативный подход, встроенная поддержка TTL. Минусы: привязан к Spring.

3. Redis Cache

Для распределённых систем используется Redis.

@Service
public class RedisApiService {
    private final RestTemplate restTemplate;
    private final RedisTemplate<String, UserData> redisTemplate;

    public UserData getUserData(String userId) {
        String key = "api:user:" + userId;
        UserData cached = redisTemplate.opsForValue().get(key);
        if (cached != null) {
            return cached;
        }
        UserData data = restTemplate.getForObject(
            "https://external-api.com/users/" + userId,
            UserData.class
        );
        redisTemplate.opsForValue().set(key, data, Duration.ofHours(1));
        return data;
    }
}

Плюсы: работает в распределённых системах, высокая производительность. Минусы: требует отдельного сервиса.

Рекомендации

In-Memory Cache: одноэкземплярные приложения, маленькие данные, допустима потеря при перезагрузке.

Redis: распределённые системы, высокая нагрузка, нужна консистентность между инстансами.

Spring Cache: Spring-приложения когда не критична распределённая консистентность.

Выбор зависит от требований масштабирования, консистентности и архитектуры приложения.