重要!找到解决方案。下面的一切都对我而言很好。这几乎是唯一可以从问题中复制解决方案的情况。有关它,请阅读“我的配置”部分
主要问题
尝试打开主页时(通过 https 443 或 http 80 均可)我看到 503 Varnish 错误。看来 Varnish 无法重新访问 Nginx。
Varnish 请求日志
* << Request >> 20
- Begin req 19 rxreq
- Timestamp Start: 1587133057.263443 0.000000 0.000000
- Timestamp Req: 1587133057.263443 0.000000 0.000000
- VCL_use boot
- ReqStart 192.168.112.7 46616 a0
- ReqMethod GET
- ReqURL /
- ReqProtocol HTTP/1.0
- ReqHeader X-Real-IP: 192.168.112.1
- ReqHeader X-Forwarded-For: 192.168.112.1
- ReqHeader X-Forwarded-Proto: https
- ReqHeader X-Forwarded-Port: 443
- ReqHeader Host: magento2.docker
- ReqHeader Connection: close
- ReqHeader Cache-Control: max-age=0
- ReqHeader Upgrade-Insecure-Requests: 1
- ReqHeader User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36
- ReqHeader Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
- ReqHeader Sec-Fetch-Site: none
- ReqHeader Sec-Fetch-Mode: navigate
- ReqHeader Sec-Fetch-User: ?1
- ReqHeader Sec-Fetch-Dest: document
- ReqHeader Accept-Encoding: gzip, deflate, br
- ReqHeader Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7,be;q=0.6
- ReqHeader Cookie: mage-banners-cache-storage=%7B%7D; _ga=GA1.2.164324136.1586263205; private_content_version=b9dd22e11f7865017754892a623f70f0; mage-cache-storage=%7B%7D; mage-cache-storage-section-invalidation=%7B%7D; mage-messages=; recently_viewed_product=%7B%7D
- ReqUnset X-Forwarded-For: 192.168.112.1
- ReqHeader X-Forwarded-For: 192.168.112.1, 192.168.112.7
- VCL_call RECV
- VCL_return pass
- VCL_call HASH
- VCL_return lookup
- VCL_call PASS
- VCL_return fetch
- Link bereq 21 pass
- Timestamp Fetch: 1587133057.263600 0.000157 0.000157
- RespProtocol HTTP/1.1
- RespStatus 503
- RespReason Backend fetch failed
- RespHeader Date: Fri, 17 Apr 2020 14:17:37 GMT
- RespHeader Server: Varnish
- RespHeader Content-Type: text/html; charset=utf-8
- RespHeader Retry-After: 5
- RespHeader X-Varnish: 20
- RespHeader Age: 0
- RespHeader Via: 1.1 varnish (Varnish/6.2)
- VCL_call DELIVER
- VCL_return deliver
- Timestamp Process: 1587133057.263609 0.000166 0.000009
- Filters
- RespHeader Content-Length: 279
- RespHeader Connection: close
- Timestamp Resp: 1587133057.263640 0.000197 0.000031
- ReqAcct 1164 0 1164 242 279 521
- End
* << BeReq >> 21
- Begin bereq 20 pass
- VCL_use boot
- Timestamp Start: 1587133057.263477 0.000000 0.000000
- BereqMethod GET
- BereqURL /
- BereqProtocol HTTP/1.0
- BereqHeader X-Real-IP: 192.168.112.1
- BereqHeader X-Forwarded-Proto: https
- BereqHeader X-Forwarded-Port: 443
- BereqHeader Host: magento2.docker
- BereqHeader Cache-Control: max-age=0
- BereqHeader Upgrade-Insecure-Requests: 1
- BereqHeader User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36
- BereqHeader Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
- BereqHeader Sec-Fetch-Site: none
- BereqHeader Sec-Fetch-Mode: navigate
- BereqHeader Sec-Fetch-User: ?1
- BereqHeader Sec-Fetch-Dest: document
- BereqHeader Accept-Encoding: gzip, deflate, br
- BereqHeader Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7,be;q=0.6
- BereqHeader Cookie: mage-banners-cache-storage=%7B%7D; _ga=GA1.2.164324136.1586263205; private_content_version=b9dd22e11f7865017754892a623f70f0; mage-cache-storage=%7B%7D; mage-cache-storage-section-invalidation=%7B%7D; mage-messages=; recently_viewed_product=%7B%7D
- BereqHeader X-Forwarded-For: 192.168.112.1, 192.168.112.7
- BereqProtocol HTTP/1.1
- BereqHeader X-Varnish: 21
- VCL_call BACKEND_FETCH
- VCL_return fetch
- FetchError backend default: fail errno 111 (Connection refused)
- Timestamp Beresp: 1587133057.263561 0.000084 0.000084
- Timestamp Error: 1587133057.263564 0.000087 0.000002
- BerespProtocol HTTP/1.1
- BerespStatus 503
- BerespReason Service Unavailable
- BerespReason Backend fetch failed
- BerespHeader Date: Fri, 17 Apr 2020 14:17:37 GMT
- BerespHeader Server: Varnish
- VCL_call BACKEND_ERROR
- BerespHeader Content-Type: text/html; charset=utf-8
- BerespHeader Retry-After: 5
- VCL_return deliver
- Storage malloc Transient
- Length 279
- BereqAcct 0 0 0 0 0 0
- End
我的配置
源代码可以在这里找到: https://github.com/zhartaunik/magento2-docker
以下是一些必将载入历史史册的时刻:
docker-compose.yml
version: "3"
services:
varnish:
container_name: varnish
build:
context: varnish/
ports:
- 6081:6081
nginx:
container_name: nginx
build:
context: nginx/
working_dir: /etc/nginx
ports:
# {internal_in_docker}:{external_from_browser}
- 80:80
- 443:443
- 8001:8001
volumes:
- ./magento:/var/www/magento
env_file:
- ./.env
...
nginx/etc/vhost.conf
upstream fastcgi_backend {
server magento:9000;
}
server {
listen 80;
listen 443 ssl;
server_name _;
ssl on;
ssl_certificate /etc/nginx/ssl/magento.crt;
ssl_certificate_key /etc/nginx/ssl/magento.key;
keepalive_timeout 300s;
location / {
proxy_pass http://varnish:6081;
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 X-Forwarded-Port 443;
proxy_set_header Host $host;
proxy_read_timeout 600s;
}
}
server {
listen 8001;
server_name localhost;
set $MAGE_ROOT /var/www/magento;
set $MAGE_MODE developer;
我遇到这个问题是因为我没有使用所需的 varnish.vcl。如果你使用这个,一切都会正常
清漆/etc/varnish.vcl
vcl 4.0;
import std;
# The minimal Varnish version is 4.0
# For SSL offloading, pass the following header in your proxy server or load balancer: 'SSL-OFFLOADED: https'
backend default {
.host = "nginx";
.port = "8001";
}
...
根据我的理解它应该如何工作
- 我们通过浏览器主页打开:https://magento2.docker/
- 由于内部
docker-compose.yml
配置了 Nginx 监听 443 端口,我们进入它的vhost.conf
部分(第一部分) - 由于该行,
proxy_pass http://varnish:6081;
我们正通过 6081 端口指向清漆容器。 nginx_container> telnet varnish 6081
返回 SUCCESS- 根据
docker-compose.yml
varnish 配置监听 6081 (是否确实需要将此端口添加到 yml 中?)我们步行到varnish/etc/varnish.vcl
(该文件是否只包含backend default
用于调试目的的部分?) - 在里面
backend default
我们看到 host=nginx,port=8001。这应该会引导我们到 Nginx。varnish_container> telnet Nginx 8001
返回 SUCCESS。然而,看起来我们不会直接使用 Nginx - 第二部分
vhost.conf
不起作用。如果我们尝试打开http://magento2.docker:8001/Nginx 解析该主机并且应用程序开始工作。
我在这里寻找什么
- 问题的解决方案
- 上面两个加粗的问题
- 有什么调试建议吗?如何从 varnish 容器检查 Nginx 的响应是什么?
更新 #1(已找到解决方案)
我已经测试了你的 Docker 设置,我注意到的主要事情是你的 varnish 容器中 /etc/varnish/default.vcl 的后端定义如下:backend default { .host = "127.0.0.1"; .port = "8080"; }
我在 DockerFile 中发现了一个错误。我使用了默认配置,并且主机/端口设置错误。我改变了这个值并且一切都开始正常工作。
以下是资料来源(您可以在https://github.com/zhartaunik/magento2-docker):
清漆/Dockerfile
FROM varnish:6.2
COPY etc/varnish.vcl /etc/varnish/
COPY bin/docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh
ENV VARNISH_CONFIG /etc/varnish/varnish.vcl
ENV VARNISH_STORAGE malloc,2048m
ENV VARNISH_LISTEN :6081
ENV VARNISH_MANAGEMENT_LISTEN 127.0.0.1:6082
EXPOSE 6081
EXPOSE 6082
ENTRYPOINT ["/bin/bash", "/docker-entrypoint.sh"]
varnish/bin/docker-entrypoint.sh
#!/bin/bash
set -e
exec varnishd \
-j unix,user=vcache \
-F \
-f ${VARNISH_CONFIG} \
-s ${VARNISH_STORAGE} \
-a ${VARNISH_LISTEN} \
-T ${VARNISH_MANAGEMENT_LISTEN} \
-p feature=+esi_ignore_https \
${VARNISH_DAEMON_OPTS}
我还删除了depends_on
部分内容。
答案1
/etc/varnish/default.vcl
我已经测试了您的 Docker 设置,我注意到的主要一点是您的容器中的后端定义varnish
如下:
backend default {
.host = "127.0.0.1";
.port = "8080";
}
这当然会导致连接被拒绝错误。
当我将其更改为以下内容时,它确实有效
backend default {
.host = "nginx";
.port = "8001";
}
在向 Varnish 发送第一个请求之前,我运行了以下命令来检查将使用哪个后端:
调试
root@a5ddd5873f9a:/etc/varnish# varnishlog -i backendopen
* << BeReq >> 17
- BackendOpen 25 default 172.31.0.9 8001 172.31.0.2 58070
* << Request >> 16
* << Session >> 15
一旦连接打开,BackendOpen
标签就不会出现在您的varnishlog
输出中。
在您的情况下,BackendOpen
它从未出现在日志中,因为您从未成功打开后端连接。
在 Varnish 中持续监控后端服务器运行状况的简单方法是按照probes
下图所示进行关联:
backend default {
.host = "nginx";
.port = "8001";
.probe = {
.url = "/";
.timeout = 1s;
.interval = 5s;
.window = 5;
.threshold = 3;
}
}
您可以通过运行来监控健康状况varnishlog -g raw
,如下所示:
root@a5ddd5873f9a:/etc/varnish# varnishlog -g raw
0 Backend_health - default Still sick 4---X-R- 0 3 5 0.001804 0.000000 HTTP/1.1 404 Not Found
在这种情况下,后端是,
sick
因为/
URL 返回一个HTTP/1.1 404 Not Found
。如果您确保这是一个HTTP/1.1 200 OK
,则健康检查将通过,并且您将不知道 Varnish 尝试连接到哪个后端。
潜在的依赖问题
但是,您的文件中可能还存在一些depends_on
问题docker-compose.yml
:
- Varnish 依赖于 Nginx。如果 Nginx 没有按时启动,Varnish 就无法解析
nginx
其用作后端的主机名。 - Nginx 依赖于 Varnish。如果 Varnish 未按时启动,Nginx 将无法解析
varnish
代理流量所需的主机名。
这有点像循环依赖。请提前检查,确保您没有遇到这些问题。
为了使您的设置正常工作,我必须确保 Nginx 依赖于 Varnish,否则 Nginx 容器将无法启动。但我必须从 Varnis 中删除 Nginx 依赖项,否则我将陷入循环依赖循环。
结论
在您的docker-compose
设置中,您的 VCL 文件没有指向正确的 Nginx 后端。
一个不太可能出现的问题是依赖项配置错误:如果容器没有按正确的顺序启动,则当容器出于代理原因需要主机名时,主机名将无法访问。再次强调:不太可能。