Gymterview
middle

Как работает HTTP-кэширование?

HTTP-кэширование — это механизм протокола HTTP, позволяющий клиенту (браузеру) и промежуточным серверам (CDN, proxy) хранить и переиспользовать ответы сервера без повторного обращения к нему.

Заголовки кэширования

Пример
HTTP/1.1 200 OK
Cache-Control: max-age=3600, public
ETag: "abc123"
Last-Modified: Tue, 22 Apr 2026 10:00:00 GMT
Заголовок Назначение Пример
Cache-Control Управление кэшированием max-age=3600, public
ETag Хэш содержимого для условных запросов "abc123"
Last-Modified Дата последнего изменения Tue, 22 Apr 2026 10:00:00 GMT
Vary По каким заголовкам различать кэш Vary: Accept-Encoding

Директивы Cache-Control

Директива Значение
public Можно кэшировать где угодно (CDN, proxy)
private Только в браузере (содержит персональные данные)
no-cache Кэшировать, но всегда проверять актуальность (через ETag/Last-Modified)
no-store Не кэшировать вообще (sensitive данные)
max-age=N Свежесть в секундах
must-revalidate После истечения max-age обязательно проверить

Условные запросы (conditional requests)

Пример
1. Первый запрос:
   GET /api/products/1 → 200 OK, ETag: "abc123"

2. Повторный запрос (с ETag):
   GET /api/products/1
   If-None-Match: "abc123"

3. Если данные не изменились:
   304 Not Modified (тело НЕ передаётся — экономия трафика)

4. Если изменились:
   200 OK, ETag: "def456", новое тело

Реализация в Spring

Пример
@GetMapping("/products/{id}")
public ResponseEntity<Product> getProduct(@PathVariable Long id) {
    Product product = productService.findById(id);
    String etag = "\"" + product.getVersion() + "\"";

    return ResponseEntity.ok()
        .cacheControl(CacheControl.maxAge(Duration.ofMinutes(10)).cachePublic())
        .eTag(etag)
        .body(product);
}

// Или с Spring ShallowEtagHeaderFilter (автоматический ETag по содержимому)
@Bean
public FilterRegistrationBean<ShallowEtagHeaderFilter> etagFilter() {
    return new FilterRegistrationBean<>(new ShallowEtagHeaderFilter());
}

Ключевые принципы

  • Cache-Control: no-cache НЕ означает “не кэшировать”; это “кэшировать, но проверять актуальность”
  • Cache-Control: no-store — единственный способ полностью запретить кэширование
  • ETag + If-None-Match дают 304 Not Modified — экономия трафика без потери актуальности
  • CDN кэширует только public ответы

Частые ошибки

  • Не устанавливать Cache-Control — браузер может кэшировать по эвристике, или не кэшировать вообще
  • no-cache вместо no-store — путаница; no-cache всё ещё кэширует
  • Кэшировать персональные данные как public — CDN может отдать чужие данные
  • Забыть Vary: Authorization — ответы для разных пользователей смешиваются в кэше

Как используется в 2026

  • CDN (Cloudflare, CloudFront) — стандарт для статики и API
  • stale-while-revalidate — директива Cache-Control для фонового обновления
  • API Gateway (Spring Cloud Gateway, Nginx) — кэширование на уровне gateway

На собеседовании: интервьюер обязательно спросит разницу между no-cache и no-store — это классическая ловушка. Частая ошибка — думать, что no-cache запрещает кэширование.