Удаление ключа в кеше 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. Скорее всего, лучшее место - это исходная кодовая база.