Я использую модуль FRiCKLE ngx_cache_purge для аннулирования кешей прокси. Я столкнулся с проблемой невозможности очистить кеши при доступе к URL-адресу недействительности с другой частью URL-адреса HOST, чем та, которая использовалась для доступа к исходному контенту. Например, если я получаю доступ к такому контенту:
curl -H 'Content-Type: application/json' -d '{ "token": "pts7v4nqf7stfq35qeb570v5n2" }' -X POST -D - http://api.example.com/news/article/cache-testing
Кэш-файл создается с соответствующим ключом, и он работает, последующие запросы обслуживаются правильно. Когда содержимое изменяется, чтобы очистить кешированные данные, бэкэнд выполняет аналогичные действия на всех веб-серверах:
curl -D - http://10.200.100.101:8080/invalidate_cached_url/POST/news/article/cache-testing
И это возвращает 404, поскольку файл кеша каким-то образом создается с host
часть URL-адреса, и чтобы очистить ее, я должен вызвать URL-адрес недействительности с тем же хостом в строке. Это проблема, поскольку у меня есть балансировщик нагрузки перед веб-стеком.
Чтобы доказать это, я сохранил файл кеша, сгенерированный указанным выше методом, и очистил кеш, затем я посетил конечную точку api напрямую с IP-адресом:
curl -H 'Content-Type: application/json' -d '{ "token": "pts7v4nqf7stfq35qeb570v5n2" }' -X POST -D - http://10.200.100.101:8080/news/article/cache-testing
Теперь, когда я пытаюсь очистить кеш, как указано выше, он работает. И правда, файлы кеша разные, но на двоичном уровне, но ключи те же.
Есть ли способ обойти это?
Вот мой конфиг:
proxy_cache_path /tmp/nginx/example-api levels=1:2 keys_zone=example_api_zone:300m inactive=1h;
upstream origin_api {
server localhost:8888;
}
server {
listen 8080 default_server;
server_name api.example.com;
proxy_buffering on;
proxy_buffer_size 1k;
proxy_buffers 24 4k;
proxy_busy_buffers_size 8k;
proxy_max_temp_file_size 2048m;
proxy_temp_file_write_size 32k;
proxy_cache_key $request_method$uri;
access_log /var/log/nginx/example-api.access.log;
error_log /var/log/nginx/example-api.error.log;
error_page 500 502 /502.html;
location = /502.html {
internal;
root /opt/errors;
}
location / {
gzip on;
include example_proxy_params.conf;
proxy_cache_bypass $http_cache_control;
proxy_cache_methods POST GET;
proxy_pass http://origin_api;
}
location ~ ^/news/singlearticle/ {
gzip on;
proxy_hide_header Cache-Control;
add_header Cache-Control 'max-age=10s, no-cache ,public';
include example_proxy_params.conf;
proxy_cache_bypass $http_cache_control;
proxy_cache_methods POST GET;
proxy_pass http://origin_api;
}
location ~ ^/news/subcategory/ {
proxy_cache_key "$request_method$request_uri|$request_body";
include example_proxy_params.conf;
proxy_cache_bypass $http_cache_control;
proxy_cache_methods POST GET;
proxy_pass http://origin_api;
}
location ~ /invalidate_cached_url/(.*) {
allow 127.0.0.1;
allow 10.200.100.101;
allow 10.200.100.102;
deny all;
proxy_cache_purge example_api_zone $1;
}
}
Оказывается, решение состоит в том, чтобы добавить Origin
заголовок, поскольку nginx фактически использует его для создания хеш-файла, и это также имеет смысл, если вы задумаетесь. Это успешно с любого разрешенного IP:
curl -H 'Origin: http://testing.bktvnews.com' -D - http://10.200.100.101:8080/invalidate_cached_url/POST/news/article/cache-testing
Задайте имя хоста в вашем curl
команда, например:
curl -H "Host: api.example.com" -D - http://192.168.255.230:8080/invalidate_cached_url/....