Реализация кэширования ответов на уровне API Gateway
Кэш на уровне gateway работает до того, как запрос доходит до бэкенда. Правильно настроенное кэширование убирает 30–70% нагрузки с сервисов без изменения их кода. Неправильно настроенное — отдаёт чужие данные чужим пользователям или держит устаревшие ответы сутками.
Что кэшировать, а что нет
Кэшировать безопасно:
-
GET-запросы с публичными данными (каталог, справочники, статьи) - Ответы с явными
Cache-Control: public, max-age=Nот upstream - Эндпоинты, которые не зависят от идентификатора сессии
Не кэшировать:
- Любые
POST,PUT,PATCH,DELETE - Запросы с заголовком
Authorization: Bearer ...— если только не настроена изоляция по пользователю - Ответы со статусом 4xx/5xx (кроме 404 на публичные ресурсы, если это осознанно)
- Данные с персональной информацией
Kong Gateway: плагин proxy-cache
plugins:
- name: proxy-cache
config:
response_code: [200, 301, 404]
request_method: [GET, HEAD]
content_type:
- application/json
- application/json; charset=utf-8
cache_ttl: 300
strategy: memory
memory:
dictionary_name: kong_db_cache
Для production — стратегия redis вместо memory:
strategy: redis
redis:
host: redis.internal
port: 6379
timeout: 2000
database: 0
password: ${REDIS_PASSWORD}
Kong добавляет заголовок X-Cache-Status в ответ: Hit, Miss, Bypass, Refresh. По нему удобно дебажить.
Инвалидация кэша через Admin API:
# Удалить конкретный ключ
curl -X DELETE http://kong-admin:8001/proxy-cache/caches/{cache_key}
# Очистить весь кэш
curl -X DELETE http://kong-admin:8001/proxy-cache/
AWS API Gateway + ElastiCache
В AWS нативного кэша на уровне gateway нет для HTTP APIs, но есть для REST APIs:
{
"cacheClusterEnabled": true,
"cacheClusterSize": "0.5",
"methodSettings": {
"GET /products": {
"cachingEnabled": true,
"cacheTtlInSeconds": 300,
"cacheDataEncrypted": false,
"requireAuthorizationForCacheControl": false
}
}
}
Terraform:
resource "aws_api_gateway_stage" "main" {
deployment_id = aws_api_gateway_deployment.main.id
rest_api_id = aws_api_gateway_rest_api.main.id
stage_name = "v1"
cache_cluster_enabled = true
cache_cluster_size = "0.5"
method_settings {
resource_path = "/products"
http_method = "GET"
settings {
caching_enabled = true
cache_ttl_in_seconds = 300
}
}
}
Инвалидация через запрос с заголовком Cache-Control: max-age=0 — если у клиента есть право execute-api:InvalidateCache.
Nginx: proxy_cache
Если gateway на Nginx:
proxy_cache_path /var/cache/nginx/api
levels=1:2
keys_zone=api_cache:10m
max_size=1g
inactive=10m
use_temp_path=off;
server {
location /api/v1/catalog/ {
proxy_cache api_cache;
proxy_cache_valid 200 5m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503;
proxy_cache_background_update on;
proxy_cache_lock on;
# Ключ кэша — без параметров авторизации
proxy_cache_key "$scheme$request_method$host$uri$is_args$args";
# Не кэшировать, если клиент передаёт куку сессии
proxy_cache_bypass $cookie_session_id;
proxy_no_cache $cookie_session_id;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://backend;
}
}
proxy_cache_use_stale updating + proxy_cache_background_update on — паттерн stale-while-revalidate: пользователь получает старый ответ мгновенно, обновление идёт в фоне. Критично для нагруженных эндпоинтов.
Vary и кэш-пространства
Если API отдаёт разные ответы в зависимости от заголовков, нужно настраивать ключ кэша правильно. Типичный пример — мультиязычный API:
# Разделяем кэш по языку
proxy_cache_key "$scheme$request_method$host$uri$is_args$args$http_accept_language";
В Kong через vary_headers:
config:
vary_headers:
- Accept-Language
- Accept-Encoding
Если этого не сделать, первый пользователь с Accept-Language: en «занимает» кэш, и все остальные получают английский ответ.
Cache stampede
При истечении TTL популярного ключа несколько воркеров одновременно идут в upstream — «кэш-шторм». Защита:
-
Mutex/lock: только один воркер обновляет, остальные ждут (
proxy_cache_lock onв Nginx) - Probabilistic early expiration: обновляем кэш чуть раньше TTL с вероятностью, растущей по мере приближения к сроку истечения
- Stale responses: отдаём устаревший ответ пока идёт обновление
Сроки
Базовая настройка кэша для 2–3 роутов: 1 день. Полноценная стратегия с инвалидацией, Vary, мониторингом hit rate и stale-while-revalidate: 3–5 дней.







