清漆:使用Nginx + Docker时,后端抓取失败

我有点失落,因为我正在经历一个清漆503错误,而在一个docker-compose容器中使用它。

varnishlog返回这个:

 varnish_1 | * << BeReq >> 3 varnish_1 | - Begin bereq 2 pass varnish_1 | - Timestamp Start: 1503505759.849314 0.000000 0.000000 varnish_1 | - BereqMethod GET varnish_1 | - BereqURL / varnish_1 | - BereqProtocol HTTP/1.1 varnish_1 | - BereqHeader Host: localhost varnish_1 | - BereqHeader Pragma: no-cache varnish_1 | - BereqHeader Cache-Control: no-cache varnish_1 | - BereqHeader Upgrade-Insecure-Requests: 1 varnish_1 | - BereqHeader User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36 varnish_1 | - BereqHeader Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 varnish_1 | - BereqHeader Accept-Encoding: gzip, deflate, br varnish_1 | - BereqHeader Accept-Language: de,de-DE;q=0.8,en-US;q=0.6,en;q=0.4 varnish_1 | - BereqHeader X-Forwarded-For: 172.18.0.1, 172.18.0.1 varnish_1 | - BereqHeader Via: varnish-default varnish_1 | - BereqHeader startedAt: 1503505759.849 varnish_1 | - BereqHeader X-Varnish: 3 varnish_1 | - VCL_call BACKEND_FETCH varnish_1 | - VCL_return fetch varnish_1 | - FetchError no backend connection varnish_1 | - Timestamp Beresp: 1503505759.849366 0.000052 0.000052 varnish_1 | - Timestamp Error: 1503505759.849370 0.000056 0.000004 varnish_1 | - BerespProtocol HTTP/1.1 varnish_1 | - BerespStatus 503 varnish_1 | - BerespReason Service Unavailable varnish_1 | - BerespReason Backend fetch failed varnish_1 | - BerespHeader Date: Wed, 23 Aug 2017 16:29:19 GMT varnish_1 | - BerespHeader Server: Varnish varnish_1 | - VCL_call BACKEND_ERROR varnish_1 | - BerespHeader Content-Type: text/html; charset=utf-8 varnish_1 | - BerespHeader Retry-After: 5 varnish_1 | - VCL_return deliver varnish_1 | - Storage malloc Transient varnish_1 | - ObjProtocol HTTP/1.1 varnish_1 | - ObjStatus 503 varnish_1 | - ObjReason Backend fetch failed varnish_1 | - ObjHeader Date: Wed, 23 Aug 2017 16:29:19 GMT varnish_1 | - ObjHeader Server: Varnish varnish_1 | - ObjHeader Content-Type: text/html; charset=utf-8 varnish_1 | - ObjHeader Retry-After: 5 varnish_1 | - Length 278 varnish_1 | - BereqAcct 0 0 0 0 0 0 varnish_1 | - End 

这是我的default.vcl的内容:

 # varnish version 4 vcl 4.0; import std; import directors; # backend start backend default { .host = "web"; .port = "80"; .connect_timeout = 30s; .first_byte_timeout = 600s; .between_bytes_timeout = 1s; .probe = { .url = "/robots.txt"; .interval = 10s; .timeout = 5s; .window = 5; .threshold = 3; } } # backend end ############# # Housekeeping # init start sub vcl_init { new magento2 = directors.fallback(); magento2.add_backend(default); } # init end sub vcl_fini { return (ok); } ############# # Client side acl purge { "web"; "php"; "localhost"; } sub vcl_recv { call custom_ctrl; if (req.method == "PURGE") { if (client.ip !~ purge) { return (synth(405, "Method not allowed")); } if (!req.http.X-Magento-Tags-Pattern) { return (synth(400, "X-Magento-Tags-Pattern header required")); } ban("obj.http.X-Magento-Tags ~ " + req.http.X-Magento-Tags-Pattern); return (synth(200, "Purged")); } /* We do not support SPDY or HTTP/2.0 */ if (req.method == "PRI") { return (synth(405)); } if (req.restarts == 0) { /* set X-Forwarded-For */ 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; } /* set Via */ if (req.http.Via) { set req.http.Via = req.http.Via + ", varnish-default"; } else { set req.http.Via = "varnish-default"; } set req.http.startedAt = std.time2real(now, 0.0); } /* backend selector */ if (req.url ~ "^/max") { set req.backend_hint = magento2.backend(); } if (req.method != "GET" && req.method != "HEAD" && req.method != "PUT" && req.method != "POST" && req.method != "TRACE" && req.method != "OPTIONS" && req.method != "DELETE") { /* Non-RFC2616 or CONNECT which is weird. */ return (pipe); } /* Implementing websocket support (https://www.varnish-cache.org/docs/4.0/users-guide/vcl-example-websockets.html) */ if (req.http.Upgrade ~ "(?i)websocket") { return (pipe); } if (req.method != "GET" && req.method != "HEAD") { /* We only deal with GET and HEAD by default */ return (pass); } /* Not cacheable */ if (req.http.Authorization) { return (pass); } # no cache request if (req.http.Cache-Control == "no-cache" || req.url ~ "cache-control=no-cache") { return (pass); } # Send Surrogate-Capability headers to announce ESI support to backend # set req.http.Surrogate-Capability = "key=ESI/1.0"; # sort the query string set req.url = std.querysort(req.url); # Bypass shopping cart, checkout and search requests if (req.url ~ "/checkout" || req.url ~ "/catalogsearch") { return (pass); } # normalize url in case of leading HTTP scheme and domain set req.url = regsub(req.url, "^http[s]?://", ""); # Cookies std.collect(req.http.Cookie); # Compression filter. See https://www.varnish-cache.org/trac/wiki/FAQ/Compression if (req.http.Accept-Encoding) { if (req.url ~ "\.(jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf|flv)$") { # No point in compressing these unset req.http.Accept-Encoding; } elsif (req.http.Accept-Encoding ~ "gzip") { set req.http.Accept-Encoding = "gzip"; } elsif (req.http.Accept-Encoding ~ "deflate" && req.http.user-agent !~ "MSIE") { set req.http.Accept-Encoding = "deflate"; } else { # unkown algorithm unset req.http.Accept-Encoding; } } # Remove Google gclid parameters to minimize the cache objects set req.url = regsuball(req.url,"\?gclid=[^&]+$",""); # strips when QS = "?gclid=AAA" set req.url = regsuball(req.url,"\?gclid=[^&]+&","?"); # strips when QS = "?gclid=AAA&foo=bar" set req.url = regsuball(req.url,"&gclid=[^&]+",""); # strips when QS = "?foo=bar&gclid=AAA" or QS = "?foo=bar&gclid=AAA&bar=baz" # static files are always cacheable. remove SSL flag and cookie if (req.url ~ "^/(pub/)?(media|static)/.*\.(ico|css|js|jpg|jpeg|png|gif|tiff|bmp|mp3|ogg|svg|swf|woff|woff2|eot|ttf|otf)$") { unset req.http.Https; unset req.http.X-Forwarded-Proto; unset req.http.Cookie; } return (hash); } sub vcl_pipe { # By default Connection: close is set on all piped requests, to stop # connection reuse from sending future requests directly to the # (potentially) wrong backend. If you do want this to happen, you can undo # it here. # unset bereq.http.connection; if (req.http.upgrade) { set bereq.http.upgrade = req.http.upgrade; } return (pipe); } sub vcl_pass { return (fetch); } sub vcl_hash { if (req.http.host) { hash_data(req.http.host); } else { hash_data(server.ip); } if (req.http.cookie ~ "X-Magento-Vary=") { hash_data(regsub(req.http.cookie, "^.*?X-Magento-Vary=([^;]+);*.*$", "\1")); } # For multi site configurations to not cache each other's content if (req.http.host) { hash_data(req.http.host); } else { hash_data(server.ip); } # To make sure http users don't see ssl warning if (req.http.X-Forwarded-Proto) { hash_data(req.http.X-Forwarded-Proto); } return (lookup); } sub vcl_purge { return (synth(200, "Purged")); } sub vcl_hit { if (obj.ttl > 0s) { # A pure unadultered hit, deliver it return (deliver); } # backend is healthy if (std.healthy(req.backend_hint)) { # set the stale if(obj.ttl + std.duration(std.integer(regsub(obj.http.Cache-Control, "[\s\S]*m-stale=(\d)+[\s\S]*", "\1"), 2) + "s", 2s) > 0s){ return (deliver); } } else if (obj.ttl + obj.grace > 0s) { # Object is in grace, deliver it # Automatically triggers a background fetch return (deliver); } # fetch & deliver once we get the result return (miss); } sub vcl_miss { return (fetch); } sub vcl_deliver { # Happens when we have all the pieces we need, and are about to send the # response to the client. # # You can do accounting or modifying the final object here. set resp.http.X-Hits = obj.hits; set req.http.varnishUse = now - std.real2time(std.real(req.http.startedAt, 0.0), now); if (resp.http.Server-Timing) { if (std.real(req.http.varnishUse, 0) > 0) { set resp.http.Server-Timing = "9=" + req.http.varnishUse + ";Varnish," + resp.http.Server-Timing; } else { set resp.http.Server-Timing = "9=0.000;Varnish," + resp.http.Server-Timing; } } else { if (std.real(req.http.varnishUse, 0) > 0) { set resp.http.Server-Timing = "9=" + req.http.varnishUse + ";Varnish"; } else { set resp.http.Server-Timing = "9=0.000;Varnish"; } } return (deliver); } # custom control sub custom_ctrl{ #响应healthy检测if(req.url == "/ping"){ return(synth(701)); } if(req.url == "/varnish/version") { return(synth(702)); } } sub vcl_synth { if (resp.status == 701) { synthetic("pong"); } elsif (resp.status == 702) { synthetic("2017-08-20T16:27:55.780Z"); } set resp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0"; set resp.status = 200; set resp.http.Content-Type = "text/plain; charset=utf-8"; return (deliver); } ############### # Backend Fetch sub vcl_backend_fetch { return (fetch); } sub vcl_backend_response { if (bereq.uncacheable) { return (deliver); } if (beresp.http.content-type ~ "text") { set beresp.do_esi = true; } # cache only successfully responses and 404s if (beresp.status != 200 && beresp.status != 404) { set beresp.ttl = 0s; set beresp.uncacheable = true; return (deliver); } elsif (beresp.http.Cache-Control ~ "private") { set beresp.uncacheable = true; set beresp.ttl = 86400s; return (deliver); } if (beresp.http.X-Magento-Debug) { set beresp.http.X-Magento-Cache-Control = beresp.http.Cache-Control; } # validate if we need to cache it and prevent from setting cookie # images, css and js are cacheable by default so we have to remove cookie also if (beresp.ttl > 0s && (bereq.method == "GET" || bereq.method == "HEAD")) { unset beresp.http.set-cookie; if (bereq.url !~ "\.(ico|css|js|jpg|jpeg|png|gif|tiff|bmp|gz|tgz|bz2|tbz|mp3|ogg|svg|swf|woff|woff2|eot|ttf|otf)(\?|$)") { set beresp.http.Pragma = "no-cache"; set beresp.http.Expires = "-1"; set beresp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0"; set beresp.grace = 1m; } } # the response body is text, do gzip (judge by response header Content-Type) if (beresp.http.Content-Type ~ "text" || beresp.http.Content-Type ~ "application/javascript" || beresp.http.Content-Type ~ "application/json") { set beresp.do_gzip = true; } # The following scenarios set uncacheable if (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Surrogate-Control ~ "no-store" || (!beresp.http.Surrogate-Control && beresp.http.Cache-Control ~ "no-cache|no-store|private") || beresp.http.Vary == "*"){ # Hit-For-Pass set beresp.uncacheable = true; set beresp.ttl = 300s; set beresp.grace = 0s; return (deliver); } # Pause ESI request and remove Surrogate-Control header if (beresp.http.Surrogate-Control ~ "ESI/1.0") { unset beresp.http.Surrogate-Control; set beresp.do_esi = true; } return (deliver); } 

你可能想知道为什么在configuration中有.host = "web" – 这是由于docker-compose.yml -compose奇怪地为docker-compose.yml文件中的每个节点创build了链接服务的configuration,这在我的情况下是web作为nginx实例的服务名称。

我能够从varnish容器平web ,所以链接是好的。 此外,这是docker集装箱的首选和用途。

nginx正在监听端口80(像内部的清漆)。 我以前在8080上试过nginx,但是它保持听不清tcp:80,并且没有错误输出,所以我试图在80端口映射这两个服务,似乎工作正常; 但是,如果我将nginx切换到端口8080,则存在这个问题。请记住,如果在Dockerfile的web -container中使用FROM nginx ,则nginx始终正在侦听端口80,所以这也可能不是问题。

乐意提供更多信息。

在这个Github问题的答案解决了我的问题。 因为它似乎探针会造成问题。 我不知道为什么,但使用问题中标记的较小configuration文件正在工作。

https://github.com/magento/magento2/issues/10165