我有点迷茫,因为我在docker-compose容器中使用的时候遇到了一个带有Varnish的503-error。
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);
}您可能想知道为什么在配置中会有.host = "web" -这是因为docker-compose神奇地为链接服务的docker-compose.yml文件中的每个节点创建了配置,在我的例子中是web作为nginx实例的服务名。
我能够从varnish容器ping web,所以链接是正常的。此外,这也是码头容器的首选用途。
nginx正在监听端口80 (就像内部的清漆)。我之前在8080上试过nginx,但它一直在侦听tcp:80,没有错误输出,所以我试着把两个服务都映射到80端口,它似乎工作得很好;但是,如果我把nginx切换到8080端口,问题就存在了。请记住,如果您在Dockerfile文件中为web-container使用FROM nginx,nginx将始终侦听端口80,因此这也可能不是问题。
很乐意提供更多信息。
发布于 2017-08-24 00:49:07
这个Github问题的答案为我解决了这个问题。看起来,这个调查产生了一些问题。我不知道为什么,但是使用问题本身中标记的较小的配置文件是有效的。
https://stackoverflow.com/questions/45845170
复制相似问题