Удаление ключа в кеше Nginx и базе данных Backend в одном запросе

Я использую открытый исходный код Nginx в качестве веб-сервера с Proxy_cache.

У меня есть уникальный сценарий удаления ключа из кеша, а также передачи запроса на внутренние серверы для удаления ключа в БД без кэширования ответа.

Поэтому удалите ключ в кеше веб-сервера и в БД в одном запросе.
Клиент => Балансировщик нагрузки => Nginx(proxy_cache) => Приложение => PostgreSQL

например, Nginx.conf

if ( $http_x_delete_key ){
  content_by_lua_file ./purge_key.lua;
  proxy_pass          http://backend_servers; 
}

например, purge_key.lua

...
if ngx ~= nil then
    ...
    delete_file(filename)
    ngx.log(ngx.NOTICE, 'deleted')
    -- ngx.exit(ngx.OK);
    -- return
end

Блок 'if' в разделе местоположения Nginx просто останавливает поток ( как работает nginx "location if") и возвращает ответ, не отправляя его бэкэнду, и не передает запрос как есть.
Я даже скомпилировал OpenResty, используя бесплатный модуль 'ngx_cache_purge', но команда очистки также не передает запрос бэкэнду.

Обычно вы делаете тайм-аут или обновляете ключ, используя ответ сервера, но в моем случае мне нужен более явный контроль для удаления ключа в том же запросе или его ответе.

Openresty+Memcache, Apache httpd, Apache Traffic Server или Varnish (vcl_purge и pass) решают этот вариант использования или есть какой-то другой способ сделать это?

2 ответа

Я вроде нашел способ сделать это.

В зависимости от значения заголовка HTTP-запроса, запустите скрипт lua, чтобы удалить файл кэша (хэш ключа и его последние символы x+y, если уровень кэша x:y) в proxy_cache Nginx.

Использование 'access_by_lua' вместо 'content_by_lua' в качестве фазы обработчика контента всегда завершится и вернется, даже если я не напишу 'ngx.exit' или 'ngx.OK'.

Я должен запустить скрипт lua в NGX_HTTP_ACCESS_PHASE, а не в NGX_HTTP_CONTENT_PHASE, поскольку я не генерирую контент или ответ, которые должны исходить из серверной части в моем сценарии.

например, Nginx.conf

proxy_cache_bypass     $http_x_delete_key;
proxy_no_cache         $http_x_delete_key;

if ( $http_x_delete_key ){
  ...
  access_by_lua_file ./purge_key.lua;
}

Когда приходит запрос на удаление ключа, Nginx
1. Запустите скрипт lua для удаления файла кэша, но не сразу, так как он находится в фазе доступа
2. Запрос будет обходить кеш
3. При получении запроса приложение удалит ключ в БД
4. Ответ не будет кешироваться в Nginx proxy_cache

Общий подход заключается в том, чтобы приложение выполняло как удаление из кэша, так и из базы данных. В качестве альтернативы, пусть nginx размещается в lua, и то и другое.

Вообще говоря, любой многоэтапный / многоадресный вид обработки запросов - это уровень приложений, а не уровень веб-сервера / сети. Ни один прокси-сервер, управляемый конфигурацией, не должен принимать форму решения этой проблемы.

Поэтому сделайте это как часть своего приложения и решите, будет ли правильный след в исходной кодовой базе или в lua. Скорее всего, лучшее место - это исходная кодовая база.

Другие вопросы по тегам