Назад | Перейти на главную страницу

Как кэшировать некоторые запросы в зависимости от частоты запросов?

У нас есть супертяжелые API, например /api/heavy, это замедлит нашу систему в пиковое время, мы провели некоторый тест, если количество одновременных запросов больше 200, система становится медленной, а если больше 600, наша система становится недоступной.

Мы не можем добавить redis или memcached Layer прямо сейчас, потому что ему нужно обновить исходный код, что сейчас невозможно из-за некоторых проблем с контрактом.

Поэтому мы думаем поставить какой-нибудь кеш-сервер перед нашим сервером API и кэшировать эти API на 10 секунд, когда частота запросов> 500, и 3 секунды, когда скорость> 150.

Как мы можем это сделать, используя Nginx или Varnish? Или другие решения? CDN?

Вы можете добиться этого с помощью кеш-сервер Nuster

# cache /heavy for 100 seconds if be_conn greater than 10
acl heavypage path /heavy
acl tooFast be_conn ge 100
nuster rule heavy ttl 100 if heavypage tooFast

Я не знаю, является ли API частным или общим? В случае, если он частный, то есть результат API отличается для каждого пользователя, вы также можете кешировать /api/heavy на пользователя вроде этого:

nuster rule heavy key method.scheme.host.uri.cookie_sessionID ttl 100 if heavypage tooFast

Надеюсь это поможет

Возможный подход с использованием Лака: во время vcl_recv использовать Redis VMOD (отказ от ответственности: я являюсь автором) или некоторое регулирование VMOD (например, vsthrottle включен в https://github.com/varnish/varnish-modules) для проверки / обновления частоты запросов к конечной точке API. Если не превышает лимит, пропустите кеш, просто выполнив pass. В противном случае сделайте hash и кэшировать по желанию во время vcl_backend_response. Это можно легко обобщить, если требуется более одного ограничения.

vsthrottle намного проще, чем подход Redis, но, очевидно, является локальным для каждого экземпляра Varnish. Обычно это нормально для сценария дросселирования, поэтому в большинстве случаев нет необходимости добавлять Redis в свой стек.