我们的环境主要由在 IIS/ASP.Net 上运行的 SSL 网站组成。网站代码的大部分内容是报告、分析和用户特定的数据视图。我们正在扩大并发用户数量,我需要规划故障转移和集群功能。我一直在研究如何设置 nginx 和 haproxy 以及可能的 varnish 来处理 SSL 卸载、负载平衡和缓存。
我的一个问题与配置有关。从我所读的内容来看,我认为,由于我们正在运行 SSL 站点,所以 nginx 需要位于 varnish 之前。我设想的正确设置是:
*-------* *nginx* *-------* | *---------* * 清漆 * *---------* | *---------* *haproxy* *---------* |\ | - - - - - | | *------* *------* * 网络 1 * * 网络 2 * *------* *------*
首先,这是我们环境 (IIS 7.5) 的最佳情况设置吗?在大多数内容本质上是每个请求的动态内容的情况下,实施 varnish 有什么好处吗?我对这个主题的分析已经到了瘫痪的地步,似乎无法就 varnish 中间层的用例找到一个很好的答案。
我的第二个问题是如何处理单点故障。目前,我们的 ASA5510 路由到每个 Web 服务器,因此我们的单点是防火墙/连接。连接发生故障的可能性非常小,以至于我实际上只将防火墙视为我们配置中的单点故障。管理层肯定会查看上图并发现 3 个可能的新故障点。有没有办法设置它以消除任何成为所有服务器主要瓶颈的点?我找不到有关 nginx 或 haproxy 不稳定的一致报告,因此它们似乎很可靠,但我仍然希望尽可能提供故障转移。
您有什么想法或意见可以在不损害基础设施的情况下以最佳方式实现这些集成?
答案1
这与我们的设置类似,只是中间没有 varnish。nginx 和 HAProxy“服务器”位于同一个盒子上。nginx 为我们执行 SSL 卸载,然后 HAProxy 将请求发送到多个 Web 服务器之一。我们希望 HAProxy 具有增强的负载平衡功能,因此我们同时拥有两者。整个过程运行良好。
我们发现的唯一问题就是客户端 IP 地址。我们找不到方法告诉 IIS 将 x-forwarded-for IP 记录为客户端 IP,但我们发现 ASP.Net 可以要求 IIS 在日志中将一些附加信息附加到请求字符串的末尾,因此我们将客户端 IP 粘贴在那里。虽然不太理想,但确实有效。nginx 设置为添加 x-forwarded-for 标头,HAProxy 则不是设置为添加转发以获取信息(因为它只会指向 nginx)。此外,nginx 似乎只为保持活动会话中的第一个请求添加标头——同样,这不是理想的选择,但对我们来说已经足够了。
我们的 nginx 配置摘录(HAProxy 正在监听 127.0.0.1:5000):
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_buffering off;
client_body_buffer_size 64k;
}
ASP.Net 代码(在 global.asax 中)将 ip 添加到请求标头:
protected void Application_BeginRequest(Object sender, EventArgs e)
{
//If there's an X-ForwardedFor header (Proxy) append it to the query string for logging purposes.
if (HttpContext.Current.Request.Headers["X-Forwarded-For"] != null)
HttpContext.Current.Response.AppendToLog((HttpContext.Current.Request.QueryString.Count == 0 ? "" : "&") + "X-Forwarded-For=" + HttpContext.Current.Request.Headers["X-Forwarded-For"]);
答案2
就我个人而言,我会先使用 nginx - 当您的瓶颈是静态(或至少是半静态)内容时,varnish 会更快,但从您的描述来看,nginx 的内置缓存功能似乎已经足够好了;同样,对于 haproxy,它是一个比 nginx 更好的负载均衡器,但除非您正在突破负载平衡的极限,否则 nginx 可能可以很愉快地处理简单的事情。
话虽如此,如果你是通过突破缓存和负载平衡的极限,我发现同时拥有这三者是可以的,唯一的小麻烦是通过每一层跟踪客户端的 IP 地址。