主要问题

主要问题

重要!找到解决方案。下面的一切都对我而言很好。这几乎是唯一可以从问题中复制解决方案的情况。有关它,请阅读“我的配置”部分

主要问题

尝试打开主页时(通过 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.ymlvarnish 配置监听 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 后端。

一个不太可能出现的问题是依赖项配置错误:如果容器没有按正确的顺序启动,则当容器出于代理原因需要主机名时,主机名将无法访问。再次强调:不太可能。

相关内容