Что выберешь для кэширования ответа от запроса к какой-то системе
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Стратегии кэширования ответов от внешних систем
При работе с запросами к внешним системам важно выбрать правильную стратегию кэширования. Рассмотрю основные подходы.
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-приложения когда не критична распределённая консистентность.
Выбор зависит от требований масштабирования, консистентности и архитектуры приложения.