15

我正在尝试将一组 EC2 实例放在几个 Varnish 服务器后面。我们的 Varnish 配置很少更改(一年一次或两次),但我们总是出于各种原因(更新、问题、负载峰值)添加/删除/替换 Web 后端。这会产生问题,因为我们总是必须更新我们的 Varnish 配置,这导致了错误和心碎。

我想做的是管理一组后端服务器,只需在弹性负载均衡器中添加或删除它们即可。我尝试将 ELB 端点指定为后端,但出现此错误:

Message from VCC-compiler:
Backend host "XXXXXXXXXXX-123456789.us-east-1.elb.amazonaws.com": resolves to multiple IPv4 addresses.
Only one address is allowed.
Please specify which exact address you want to use, we found these:
123.123.123.1
63.123.23.2
31.13.67.3
('input' Line 2 Pos 17)
.host = "XXXXXXXXXXX-123456789.us-east-1.elb.amazonaws.com";

ELB 提供的唯一一致的公共接口是它的 DNS 名称。此 DNS 名称解析为随时间和负载而变化的 IP 地址集。

在这种情况下,我宁愿不指定一个确切的地址——我想在从 DNS 返回的任何内容之间进行循环。这可能吗?或者有人可以提出另一个解决方案来完成同样的事情吗?

谢谢,山姆

4

8 回答 8

5

您可以使用 NGINX Web 服务器来处理 CNAME 解析问题:

User-> Varnish -> NGNIX -> ELB -> EC2 Instances
        (Cache Section)        (Application Section)

您在这篇文章中有一个配置示例:http ://blog.domenech.org/2013/09/using-varnish-proxy-cache-with-amazon-web-services-elastic-load-balancer-elb.html

胡安

于 2013-10-01T11:24:11.910 回答
4

我不建议在 Varnish 后面放置 ELB。

问题在于 Varnish 正在解析分配给 ELB 的名称,并且它正在缓存 IP 地址,直到 VCL 重新加载。由于 ELB 的动态特性,链接到 cname 的 IP 可以随时更改,导致 Varnish 将流量路由到不再链接到正确 ELB 的 IP。

这是一篇您可能想阅读的有趣文章。

于 2013-01-10T10:48:21.400 回答
3

是的你可以。

在你的 default.vcl 中:

include "/etc/varnish/backends.vcl";

并将后端设置为:

set req.backend = default_director;

所以,运行这个脚本来创建 backends.vcl:

#!/bin/bash
FILE_CURRENT_IPS='/tmp/elb_current_ips'
FILE_OLD_IPS='/tmp/elb_old_ips'
TMP_BACKEND_CONFIG='/tmp/tmp_backends.vcl'
BACKEND_CONFIG='/etc/varnish/backends.vcl'

ELB='XXXXXXXXXXXXXX.us-east-1.elb.amazonaws.com'
IPS=($(dig +short $ELB | sort))

if [ ! -f $FILE_OLD_IPS ]; then
    touch $FILE_OLD_IPS
fi

echo ${IPS[@]} > $FILE_CURRENT_IPS

DIFF=`diff $FILE_CURRENT_IPS $FILE_OLD_IPS | wc -l`

cat /dev/null > $TMP_BACKEND_CONFIG

if [ $DIFF -gt 0 ]; then

    COUNT=0

    for i in ${IPS[@]}; do
        let COUNT++
        IP=$i
        cat <<EOF >> $TMP_BACKEND_CONFIG
backend app_$COUNT {
    .host = "$IP";
    .port = "80";
    .connect_timeout = 10s;
    .first_byte_timeout = 35s;
    .between_bytes_timeout = 5s;
}

EOF
    done

    COUNT=0

    echo 'director default_director round-robin {' >> $TMP_BACKEND_CONFIG

    for i in ${IPS[@]}; do
        let COUNT++
        cat <<EOF >> $TMP_BACKEND_CONFIG
    { .backend = app_$COUNT; }
EOF
    done

    echo '}' >> $TMP_BACKEND_CONFIG

    echo 'NEW BACKENDS'
    mv -f $TMP_BACKEND_CONFIG $BACKEND_CONFIG

fi

mv $FILE_CURRENT_IPS $FILE_OLD_IPS
于 2014-06-14T18:07:24.577 回答
2

我编写了这个脚本,以便在新实例启动或关闭时自动更新 vcl。

它要求 .vcl 包含对 backend.vcl

这个脚本只是解决方案的一部分,任务应该是: 1. 获取新的服务器名称和 IP(自动缩放)可以使用 AWS API cmds 来做到这一点,也可以通过 bash 2. 更新 vcl(这个脚本) 3. 重新加载清漆

脚本在这里 http://felipeferreira.net/?p=1358

其他人以不同的方式做到了 http://blog.cloudreach.co.uk/2013/01/varnish-and-autoscaling-love-story.html

于 2013-06-14T22:02:39.640 回答
1

您可以在您的私有 VPC 中创建 ELB,以便它具有本地 IP。这样您就不必使用任何 DNS 类型的 Cname 或 Varnish 不那么容易支持的任何东西。

于 2014-12-17T22:01:40.370 回答
1

如果必须在每个请求上解析一个 IP,您将无法获得 10K 请愿。Varnish 在启动时解析 ips,除非重新启动或重新加载,否则不要刷新它。实际上,如果在后端定义中找到两个 dns 名称的 ip,varnish 会拒绝启动,例如为多 az ELB 返回的 ip。

所以我们解决了一个类似的问题,将清漆放在 nginx 前面。Nginx 可以将 ELB 定义为后端,因此 Varnish 后端是本地 nginx,而 nginx 后端是 ELB。

但我对这个解决方案感到不舒服。

于 2013-09-27T13:34:27.153 回答
1

使用内部 ELB 无济于事,因为它通常有 2 个内部 IP!

后端主机“internal-XXX.us-east-1.elb.amazonaws.com”:解析为多个 IPv4 地址。只允许一个地址。请指定您要使用的确切地址,我们找到了这些地址:10.30.10.134 10.30.10.46 ('input' Line 13 Pos 12)

我不确定这些 IP 是否会始终保持不变或可以更改?任何人?

于 2015-07-13T21:11:59.263 回答
0

我之前的回答(三年多前)我还没有解决这个问题,我的 [nginx - varnish - nxinx ] -> ELB 解决方案一直有效,直到 ELB 更改 IP

但是从前一段时间我们使用相同的设置但使用jdomain 插件编译的 nginx

因此,想法是将 nginx 放置在清漆的同一主机中,然后像这样配置上游:

resolver 10.0.0.2;  ## IP for the aws resolver on the subnet

upstream backend {                                                                              
    jdomain internal-elb-dns-name port=80;
}

如果 ELB 更改其地址,则上游将自动重新配置上游 ips IP

它可能不是使用清漆的解决方案,但可以按预期工作

于 2017-03-12T11:34:50.633 回答