【问题标题】:Varnish caching for on demand domains / Multitenancy按需域/多租户的清漆缓存
【发布时间】:2022-01-03 04:00:40
【问题描述】:

我一直在尝试使用 Caddy 和 varnish 设置自定义 CDN。这个想法是按需生成 SSL 证书,然后将其传递给清漆,清漆进一步将其发送到后端服务器,这是一个 nodejs 应用程序。如果请求匹配,则 varnish 返回缓存结果,否则获取新数据。 工作在图中描述 flow diagram

以下是相应的文件: docker-compose.yml

version: '3.7'

networks:
  web:
    external: true
  internal:
    external: false
    driver: bridge

services:
 caddy:
    image: caddy
    container_name: caddy
    restart: unless-stopped
    ports:
      - "8080:8080"
      - "80:80"
      - "443:443"
    volumes:
      - $PWD/Caddyfile:/etc/caddy/Caddyfile
      - $PWD/site:/srv
      - caddy_data:/data
      - caddy_config:/config
    networks:
      - web

 varnish:
    container_name: varnish
    image: varnish:stable
    restart: unless-stopped
    volumes:
      - $PWD/data/varnish/default.vcl:/etc/varnish/default.vcl
    networks:
      - web
      - internal
volumes:
  caddy_data:
    external: true
  caddy_config:

球童文件

{
    on_demand_tls {
        ask      https://check-domain-URL
    }
}

https:// {

tls {
    on_demand
}                          

reverse_proxy varnish:80 {
                header_up Host {host}  # Won't work with another value or transparent preset
                header_up X-Forwarded-Host {host}
                header_up X-Real-IP {remote}
                header_up X-Forwarded-For {remote}
                header_up X-Forwarded-Proto {scheme}
                header_up X-Caddy-Forwarded 1
                header_down Cache-Control "public, max-age=31536000"
}

header /_next/static/* {
Cache-Control "public, max-age=31536000, immutable"
}
}

:8080 {
reverse_proxy backend-address:3000
}

default.vcl

vcl 4.0;

backend default {
    .host = "caddy";
    .port = "8080";
}

sub vcl_deliver
{
    # Insert Diagnostic header to show Hit or Miss
    if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT";
        set resp.http.X-Cache-Hits = obj.hits;
    }
    else {
        set resp.http.X-Cache = "MISS";
    }

}

sub vcl_backend_response {
    set beresp.ttl = 10s;
    set beresp.grace = 1h;

}

一切正常

  1. 正在生成 SSL 证书
  2. 代理正在工作
  3. Varnish 正在返回结果
  4. 代理正在获取后端

唯一的问题是 Varnish Cache 总是miss,这是它应该做的一件事 我已经尝试了所有方法,但看起来清漆将每个请求都视为一个新请求。 有什么想法吗?

【问题讨论】:

    标签: docker caching cdn varnish caddy


    【解决方案1】:

    要了解为什么会收到缓存未命中,您需要了解内置 VCL。

    这是在后台执行的 VCL 代码。请查看以下解释此问题的教程:https://www.varnish-software.com/developers/tutorials/varnish-builtin-vcl/

    内置 VCL 缓存绕过总结

    我想总结一下 Varnish 不缓存的标准情况:

    1. 当请求方法不是GETHEAD
    2. 当请求包含Authorization 标头时
    3. 当请求包含Cookie标头时
    4. 当响应包含Set-Cookie 标头时
    5. 由于Expires 标头或Cache-Control 标头中的max-age=0s-maxage=0 导致响应TTL 为零时
    6. 当响应在Cache-Control 标头中包含privateno-cacheno-store
    7. 当有Vary: * 响应头时

    使用 varnishlog 检查缓存未命中/绕过

    使用varnishlog 可以轻松找出缓存未命中或绕过缓存的原因。

    您可以运行以下命令来查看主页的日志:

    sudo varnishlog -g request -q "ReqUrl eq '/'"
    

    请将/改成想要的网址。

    编写 VCL 进行补偿

    如果您的应用程序的行为不符合内置 VCL 规范,则您必须编写一些 VCL 代码来弥补这一点。

    在大多数情况下,这是剥离跟踪 cookie 或定义哪些 URL 模式应绕过缓存,同时强制在所有其他页面上进行缓存查找。

    查看日志以了解具体内容,如果您需要帮助,只需在您的问题中添加日志事务,我会为您提供帮助。

    【讨论】:

    • 感谢您的共鸣,在这种情况下是 cookie 案例
    猜你喜欢
    • 2012-04-03
    • 1970-01-01
    • 2016-05-25
    • 2012-09-20
    • 1970-01-01
    • 2017-07-21
    • 1970-01-01
    • 2014-04-07
    • 2015-11-03
    相关资源
    最近更新 更多