Я немного зациклился на том, как лучше всего очистить Varnish во всех моих экземплярах на Elastic Beanstalk - к сожалению, я не очень хорошо разбираюсь в AWS.
Я хотел бы упростить настройку, поэтому я решил использовать кеш Varnish на каждом сервере, а не на отдельных серверах Varnish.
Теперь, если у меня есть сайт, который может очищать кеш, он пройдет через балансировщик нагрузки и попадет только на один сервер. Оттуда, я думаю, я мог бы достичь досягаемости своих экземпляров, но на этом этапе я не знаю, какие IP-адреса являются каждым экземпляром. Так нужно ли мне использовать AWS Cli, чтобы захватить все экземпляры, а затем запустить очистку каждого? Или есть способ, когда вызывается определенный URL (возможно, с заголовком), чтобы он достиг всех экземпляров за этим балансировщиком нагрузки.
Я был бы очень признателен за руководство по этому поводу.
Ниже приведена моя конфигурация. Одна вещь, которая может выглядеть немного странно, - это X-Purge-Token. Я решил, что это может иметь смысл, если запрос поступает от балансировщика нагрузки или другие экземпляры проверяют заголовок на токен, прежде чем разрешить очистку. Изначально я планировал использовать X-Forwarded-For, но из-за изменения IP-адресов я не был уверен, что лучший маршрут для этого.
option_settings:
- namespace: aws:elasticbeanstalk:application:environment
option_name: COMPOSER_HOME
value: /root
- option_name: APP_ENV
value: placeholder
- option_name: APP_KEY
value: placeholder
packages:
yum:
varnish: []
files:
"/etc/varnish/default.vcl":
owner: root
group: root
content: |
backend default {
.host = "127.0.0.1";
.port = "8080";
}
acl elb {
"172.31.0.0"/20;
"172.31.16.0"/20;
"172.31.32.0"/20;
}
acl purge {
"localhost";
"127.0.0.1";
"::1";
"86.19.111.22";
"213.106.111.22";
}
sub vcl_recv {
if (req.request == "PURGE") {
set req.http.xff = regsub(req.http.X-Forwarded-For, "^[^,]+.?.?(.*)$", "\1");
if(client.ip ~ elb) {
if (req.http.X-Purge-Token == "tFjn3MnrunWzi49x") {
return (lookup);
}
} else {
if (client.ip ~ purge) {
return (lookup);
}
}
error 405 "Not allowed.";
}
if (!(req.url ~ "(preview=true|wp-login|wp-admin)")) {
unset req.http.cookie;
}
}
sub vcl_fetch {
if (beresp.ttl == 120s) {
set beresp.ttl = 24h;
}
if (!(req.url ~ "(preview=true|wp-login|wp-admin)")) {
unset beresp.http.set-cookie;
}
}
sub vcl_hit {
if (req.request == "PURGE") {
if(req.http.X-Purge-Method == "regex") {
ban("req.url ~ " + req.url + " && req.http.host ~ " + req.http.host);
}
purge;
error 200 "Purged.";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
if(req.http.X-Purge-Method == "regex") {
ban("req.url ~ " + req.url + " && req.http.host ~ " + req.http.host);
}
purge;
error 200 "Purged.";
}
}
commands:
001_update_composer:
command: export COMPOSER_HOME=/root && /usr/bin/composer.phar self-update
010_httpd.conf:
command: "sed -i 's/Listen 8080/Listen 80/g' /etc/httpd/conf/httpd.conf"
011_httpd.conf:
command: "sed -i 's/Listen 80/Listen 8080/g' /etc/httpd/conf/httpd.conf"
040_varnish:
command: "sed -i 's/VARNISH_LISTEN_PORT=6081/VARNISH_LISTEN_PORT=80/g' /etc/sysconfig/varnish"
041_varnish:
command: "sed -i 's/VARNISH_ADMIN_LISTEN_PORT=6082/VARNISH_ADMIN_LISTEN_PORT=2000/g' /etc/sysconfig/varnish"
container_commands:
"1-storage-permissions":
command: "mkdir -p public/content/uploads && chmod -R 755 public/content/uploads"
"2-install-dependencies":
command: "/usr/bin/composer.phar install"
services:
sysvinit:
varnish:
enabled: true
ensureRunning: true
Я думаю, что лучше всего использовать интерфейс командной строки. Пометьте среды Elastic Beanstalk соответствующими тегами, которые можно использовать для идентификации экземпляров EC2. Например, EnvironmentName
и ServiceName
тег.
Затем вы можете выполнить следующий вызов CLI, чтобы получить частные IP-адреса этих экземпляров, которые затем можно использовать для отправки отдельных запросов на очистку.
aws ec2 describe-instances \
--region eu-west-1 \
--filter Name=tag:EnvironmentName,Values=production \
--filter Name=tag:ServiceName,Values=cache \
--query "Reservations[].Instances[].PrivateIpAddress"
Конечно, вам нужно будет заменить значения региона, EnvironmentName и ServiceName, чтобы они соответствовали вашей настройке.