如何解决 Varnish purger 在 1000 毫秒后超时,0 个字节中有 0 个字节收到 cURL 错误 28
How to solve Varnish purger that times out after 1000 milliseconds with 0 out of 0 bytes received with cURL error 28
使用 Varnish (5.2) 进行缓存工作正常,但是当更改站点上的某些内容时,缓存不会刷新并且陈旧的内容不断显示。我可以看到有一个清除队列,但没有 BAN 正在处理。 Drupal (8) 与 Varnish Purge 模块形成一个队列来获取 Varnish 中的缓存标签失效并 drush 处理它:
drush p:queue-work
------------------------ -----
Succeeded 0
Failed 100
Currently invalidating 0
Not supported 0
------------------------ -----
In QueueCommands.php line 529: Over 40% failed, please check the logs!
然后日志中出现这条消息:
purger_varnish_84f7afee13: item failed due GuzzleHttp\Exception\ConnectException, details (JSON): {"msg":"cURL error 28: Operation timed out after 1000 milliseconds with 0 out of 0 bytes received (see https:\/\/curl.haxx.se\/libcurl\/c\/libcurl-errors.html)","uri":"https:\/\/127.0.0.1:6081\/","method":"BAN","guzzle_opt":{"http_errors":true,"connect_timeout":1,"timeout":1,"verify":false},"headers":{"user-agent":"varnish_purger module for Drupal 8.","cache-tags":"config:contact.form.personal"}}
使用 cURL 手动清除 有效:
curl -X BAN http://127.0.0.1:6081/ -H "Cache-Tags: node:1042"
可能是什么问题,Varnish 似乎不接受连接或类似的东西?
/etc/varnish/usr.vcl 的内容:
vcl 4.0;
backend default {
.host = "127.0.0.1";
.port = "8080";
}
acl purge {
"127.0.0.1";
}
# Respond to incoming requests.
sub vcl_recv {
# Add an X-Forwarded-For header with the client IP address.
if (req.restarts == 0) {
if (req.http.X-Forwarded-For) {
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
}
else {
set req.http.X-Forwarded-For = client.ip;
}
}
# Only allow PURGE requests from IP addresses in the 'purge' ACL.
if (req.method == "PURGE") {
if (!client.ip ~ purge) {
return (synth(405, "Not allowed."));
}
return (hash);
}
# Only allow BAN requests from IP addresses in the 'purge' ACL.
if (req.method == "BAN") {
# Same ACL check as above:
if (!client.ip ~ purge) {
return (synth(403, "Not allowed."));
}
# Logic for the ban, using the Cache-Tags header. For more info
# see https://github.com/geerlingguy/drupal-vm/issues/397.
if (req.http.Cache-Tags) {
ban("obj.http.Cache-Tags ~ " + req.http.Cache-Tags);
}
else {
return (synth(403, "Cache-Tags header missing."));
}
# Throw a synthetic page so the request won't go to the backend.
return (synth(200, "Ban added."));
}
if (req.method == "URIBAN") {
ban("req.http.host == " + req.http.host + " && req.url == " + req.url);
# Throw a synthetic page so the request won't go to the backend.
return (synth(200, "Ban added."));
}
# Only cache GET and HEAD requests (pass through POST requests).
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}
# Pass through any administrative or AJAX-related paths.
if (req.url ~ "^/status.php$" ||
req.url ~ "^/update.php$" ||
req.url ~ "^/admin$" ||
req.url ~ "^/admin/.*$" ||
req.url ~ "^/flag/.*$" ||
req.url ~ "^.*/ajax/.*$" ||
req.url ~ "^.*/ahah/.*$") {
return (pass);
}
# Removing cookies for static content so Varnish caches these files.
if (req.url ~ "(?i).(pdf|asc|dat|txt|doc|xls|ppt|tgz|csv|png|gif|jpeg|jpg|ico|swf|css|js)(\?.*)\?$") {
unset req.http.Cookie;
}
if (req.http.Cookie) {
set req.http.Cookie = ";" + req.http.Cookie;
set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
set req.http.Cookie = regsuball(req.http.Cookie, ";(SESS[a-z0-9]+|SSESS[a-z0-9]+|NO_CACHE)=", "; =");
set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
if (req.http.Cookie == "") {
unset req.http.Cookie;
}
else {
return (pass);
}
}
}
# Set a header to track a cache HITs and MISSes.
sub vcl_deliver {
# Remove ban-lurker friendly custom headers when delivering to client.
unset resp.http.X-Url;
unset resp.http.X-Host;
# Comment these for easier Drupal cache tag debugging in development.
#unset resp.http.Cache-Tags;
#unset resp.http.X-Drupal-Cache-Contexts;
if (obj.hits > 0) {
set resp.http.Cache-Tags = "HIT";
}
else {
set resp.http.Cache-Tags = "MISS";
}
}
# Instruct Varnish what to do in the case of certain backend responses (beresp).
sub vcl_backend_response {
# Set ban-lurker friendly custom headers.
set beresp.http.X-Url = bereq.url;
set beresp.http.X-Host = bereq.http.host;
# Cache 404s, 301s, at 500s with a short lifetime to protect the backend.
if (beresp.status == 404 || beresp.status == 301 || beresp.status == 500) {
set beresp.ttl = 10m;
}
# Don't allow static files to set cookies.
# (?i) denotes case insensitive in PCRE (perl compatible regular expressions).
# This list of extensions appears twice, once here and again in vcl_recv so
# make sure you edit both and keep them equal.
if (bereq.url ~ "(?i).(pdf|asc|dat|txt|doc|xls|ppt|tgz|csv|png|gif|jpeg|jpg|ico|swf|css|js)(\?.*)?$") {
unset beresp.http.set-cookie;
}
# Allow items to remain in cache up to 6 hours past their cache expiration.
set beresp.grace = 6h;
}
我使用 NGINX 代理通过 Varnish 启用 SSL,nginx 服务器配置的内容:
server {
listen 443 ssl http2;
server_name test.example.com;
port_in_redirect off;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass http://127.0.0.1:6081;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header HTTPS "on";
proxy_set_header If-Modified-Since $http_if_modified_since;
proxy_buffering on;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
}
server {
listen 8080;
server_name test.example.com;
root /home/example/domains/test/public_html/web;
index index.php index.html index.htm index.nginx-debian.html;
port_in_redirect off;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass 127.0.0.1:9000;
}
}
server {
listen 80;
if ($host = test.example.com) {
return 301 https://$host$request_uri;
}
server_name test.example.com;
return 404;
}
Drush 无法通过 TLS.
连接到端口 6081
上的 varnish
您的日志行表明您正在使用以下 URL 连接到 Varnish:https://127.0.0.1:6081/
.
Varnish 的开源版本不支持原生 TLS,这就是您在 Nginx 中终止它的原因。
2 种可能的解决方案:
- 要么将 url 更改为
http://127.0.0.1:6081
以使用纯 HTTP
- 要么将 url 更改为
https://127.0.0.1
以通过 Nginx 使用 HTTPS
如果我是你,我会选择前者,并且只使用纯 HTTP 进行失效。它发生在内部,不会暴露在互联网上,因此使用常规 HTTP 非常安全。
使用 Varnish (5.2) 进行缓存工作正常,但是当更改站点上的某些内容时,缓存不会刷新并且陈旧的内容不断显示。我可以看到有一个清除队列,但没有 BAN 正在处理。 Drupal (8) 与 Varnish Purge 模块形成一个队列来获取 Varnish 中的缓存标签失效并 drush 处理它:
drush p:queue-work
------------------------ -----
Succeeded 0
Failed 100
Currently invalidating 0
Not supported 0
------------------------ -----
In QueueCommands.php line 529: Over 40% failed, please check the logs!
然后日志中出现这条消息:
purger_varnish_84f7afee13: item failed due GuzzleHttp\Exception\ConnectException, details (JSON): {"msg":"cURL error 28: Operation timed out after 1000 milliseconds with 0 out of 0 bytes received (see https:\/\/curl.haxx.se\/libcurl\/c\/libcurl-errors.html)","uri":"https:\/\/127.0.0.1:6081\/","method":"BAN","guzzle_opt":{"http_errors":true,"connect_timeout":1,"timeout":1,"verify":false},"headers":{"user-agent":"varnish_purger module for Drupal 8.","cache-tags":"config:contact.form.personal"}}
使用 cURL 手动清除 有效:
curl -X BAN http://127.0.0.1:6081/ -H "Cache-Tags: node:1042"
可能是什么问题,Varnish 似乎不接受连接或类似的东西?
/etc/varnish/usr.vcl 的内容:
vcl 4.0;
backend default {
.host = "127.0.0.1";
.port = "8080";
}
acl purge {
"127.0.0.1";
}
# Respond to incoming requests.
sub vcl_recv {
# Add an X-Forwarded-For header with the client IP address.
if (req.restarts == 0) {
if (req.http.X-Forwarded-For) {
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
}
else {
set req.http.X-Forwarded-For = client.ip;
}
}
# Only allow PURGE requests from IP addresses in the 'purge' ACL.
if (req.method == "PURGE") {
if (!client.ip ~ purge) {
return (synth(405, "Not allowed."));
}
return (hash);
}
# Only allow BAN requests from IP addresses in the 'purge' ACL.
if (req.method == "BAN") {
# Same ACL check as above:
if (!client.ip ~ purge) {
return (synth(403, "Not allowed."));
}
# Logic for the ban, using the Cache-Tags header. For more info
# see https://github.com/geerlingguy/drupal-vm/issues/397.
if (req.http.Cache-Tags) {
ban("obj.http.Cache-Tags ~ " + req.http.Cache-Tags);
}
else {
return (synth(403, "Cache-Tags header missing."));
}
# Throw a synthetic page so the request won't go to the backend.
return (synth(200, "Ban added."));
}
if (req.method == "URIBAN") {
ban("req.http.host == " + req.http.host + " && req.url == " + req.url);
# Throw a synthetic page so the request won't go to the backend.
return (synth(200, "Ban added."));
}
# Only cache GET and HEAD requests (pass through POST requests).
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}
# Pass through any administrative or AJAX-related paths.
if (req.url ~ "^/status.php$" ||
req.url ~ "^/update.php$" ||
req.url ~ "^/admin$" ||
req.url ~ "^/admin/.*$" ||
req.url ~ "^/flag/.*$" ||
req.url ~ "^.*/ajax/.*$" ||
req.url ~ "^.*/ahah/.*$") {
return (pass);
}
# Removing cookies for static content so Varnish caches these files.
if (req.url ~ "(?i).(pdf|asc|dat|txt|doc|xls|ppt|tgz|csv|png|gif|jpeg|jpg|ico|swf|css|js)(\?.*)\?$") {
unset req.http.Cookie;
}
if (req.http.Cookie) {
set req.http.Cookie = ";" + req.http.Cookie;
set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
set req.http.Cookie = regsuball(req.http.Cookie, ";(SESS[a-z0-9]+|SSESS[a-z0-9]+|NO_CACHE)=", "; =");
set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
if (req.http.Cookie == "") {
unset req.http.Cookie;
}
else {
return (pass);
}
}
}
# Set a header to track a cache HITs and MISSes.
sub vcl_deliver {
# Remove ban-lurker friendly custom headers when delivering to client.
unset resp.http.X-Url;
unset resp.http.X-Host;
# Comment these for easier Drupal cache tag debugging in development.
#unset resp.http.Cache-Tags;
#unset resp.http.X-Drupal-Cache-Contexts;
if (obj.hits > 0) {
set resp.http.Cache-Tags = "HIT";
}
else {
set resp.http.Cache-Tags = "MISS";
}
}
# Instruct Varnish what to do in the case of certain backend responses (beresp).
sub vcl_backend_response {
# Set ban-lurker friendly custom headers.
set beresp.http.X-Url = bereq.url;
set beresp.http.X-Host = bereq.http.host;
# Cache 404s, 301s, at 500s with a short lifetime to protect the backend.
if (beresp.status == 404 || beresp.status == 301 || beresp.status == 500) {
set beresp.ttl = 10m;
}
# Don't allow static files to set cookies.
# (?i) denotes case insensitive in PCRE (perl compatible regular expressions).
# This list of extensions appears twice, once here and again in vcl_recv so
# make sure you edit both and keep them equal.
if (bereq.url ~ "(?i).(pdf|asc|dat|txt|doc|xls|ppt|tgz|csv|png|gif|jpeg|jpg|ico|swf|css|js)(\?.*)?$") {
unset beresp.http.set-cookie;
}
# Allow items to remain in cache up to 6 hours past their cache expiration.
set beresp.grace = 6h;
}
我使用 NGINX 代理通过 Varnish 启用 SSL,nginx 服务器配置的内容:
server {
listen 443 ssl http2;
server_name test.example.com;
port_in_redirect off;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass http://127.0.0.1:6081;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header HTTPS "on";
proxy_set_header If-Modified-Since $http_if_modified_since;
proxy_buffering on;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
}
server {
listen 8080;
server_name test.example.com;
root /home/example/domains/test/public_html/web;
index index.php index.html index.htm index.nginx-debian.html;
port_in_redirect off;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass 127.0.0.1:9000;
}
}
server {
listen 80;
if ($host = test.example.com) {
return 301 https://$host$request_uri;
}
server_name test.example.com;
return 404;
}
Drush 无法通过 TLS.
连接到端口6081
上的 varnish
您的日志行表明您正在使用以下 URL 连接到 Varnish:https://127.0.0.1:6081/
.
Varnish 的开源版本不支持原生 TLS,这就是您在 Nginx 中终止它的原因。
2 种可能的解决方案:
- 要么将 url 更改为
http://127.0.0.1:6081
以使用纯 HTTP - 要么将 url 更改为
https://127.0.0.1
以通过 Nginx 使用 HTTPS
如果我是你,我会选择前者,并且只使用纯 HTTP 进行失效。它发生在内部,不会暴露在互联网上,因此使用常规 HTTP 非常安全。