使用直接服务器返回转发 HTTP 请求

使用直接服务器返回转发 HTTP 请求

我的服务器分布在多个数据中心,每个服务器都存储不同的文件。我希望用户能够通过单个域访问所有服务器上的文件,并让各个服务器直接将文件返回给用户。

下面是一个简单的例子:1)用户浏览器请求http://www.example.com/files/file1.zip 2) 根据 example.com 的 DNS A 记录,请求转到服务器 A。3) 服务器 A 分析请求并发现 /files/file1.zip 存储在服务器 B 上。4) 服务器 A 将请求转发给服务器 B。5) 服务器 B 直接将 file1.zip 返回给用户,而无需通过服务器 A。

注意:步骤 4 和 5 必须对用户透明,并且不能涉及向用户发送重定向,因为这会违反单个域的要求。

根据我的研究,我想要实现的是“直接服务器返回”,这是负载平衡的常见设置。有时也称为半反向代理。

对于步骤 4,听起来我需要进行 MAC 地址转换,然后将请求传回网络,而对于服务器 A 网络之外的服务器,则需要隧道。

对于步骤 5,我只需按照负载平衡设置中的真实服务器配置服务器 B。也就是说,服务器 B 应该在环回接口上具有服务器 A 的 IP 地址,并且它不应响应针对该 IP 地址的任何 ARP 请求。

我的问题是如何真正实现步骤 4?

我发现很多硬件和软件都可以实现第 4 层的简单负载平衡,但这些解决方案不够完善,无法处理我所需的自定义路由。看来我需要自己开发解决方案了。

理想情况下,我希望在 Web 服务器级别(即在 PHP 或 C#/ASP.net 中)进行路由/转发。但是,我愿意在较低级别(如 Apache 或 IIS)甚至更低级别(即在一切之前使用自定义代理服务)进行此操作。

谢谢。

答案1

Daniel - 您可能可以相对轻松地使用 LVS 和集群文件系统完成此操作。您的 LVS 负载均衡器将接收 HTTP 请求,并将请求转发到可以响应该请求的 Web 节点。响应将直接从 Web 节点发出,负载均衡器根本不参与回复。

我整理了一个指南(在 Fedora 上)在虚拟化 Xen 实例上运行良好。

答案2

我认为您应该使用缓存代理服务器或 HTTP 重定向来实现您的目标。

例如,使用 nginx,您可以使用后端(PHP 脚本或某些 FastCGI 托管服务器)来确定应该访问哪个“数据中心”,然后使用 proxy_pass 将 X-Accel-Redirect 返回到该数据中心的新位置。此后,nginx 应该缓存/存储您的结果。

因此,每个数据中心的配置仅针对 100% 本地的文件而不同。

第二种情况 - 后端返回 301 错误代码,并附带必要的直接链接。

答案3

丹尼尔,你真的做足了功课。也许有大师可以证明我错了,但我的第一反应是“别这么做”。我知道这有点不合逻辑,但没有任何理由为什么你确实需要这个,这是我能想到的最好的答案。虽然我认为建议的解决方案可行,但要隐藏一个域就需要进行大量的配置和设置——在我看来,这太脆弱和复杂了。

我建议:

  • 采取强硬的谈判策略,通过谈判取消单一域名要求。真正解释这会增加多少复杂性和成本。然后使用简单的 HTTP 重定向到每个服务器/站点。
  • 或者
  • 将所有数据复制到所有数据中心 (DC) 以实现冗余。使用任播使一个域在多个 DC 上可用。在每个 DC 上使用您选择的传统负载平衡器。

高血压

答案4

Linux 虚拟服务器和 keepalived 的组合,也许还有一些 arptable 魔法,应该可以实现您的要求。我过去曾广泛使用过这种方法,事实证明它具有很高的可扩展性。实际服务器在收到连接后会回复客户端,这一事实使负载平衡器 (LVS+Keepalived) 具有很高的可扩展性。

诀窍是让 arptables 正确。在 Red Hat/CentOS 上,该包名为arptables_jf。以下是从您的示例中放置在服务器 B 上的一些示例规则,假设 10.10.0.1 是您的 VIP,而 10.10.0.10 是服务器 B 的 IP:

arptables -A IN -d 10.10.0.1 -j DROP 
arptables -A OUT -s 10.10.0.1 -j mangle --mangle-ip-s 10.10.0.10

请注意,您的负载平衡器(服务器 A)和真实服务器(服务器 B+)应位于同一网络上。

您还需要为每个真实服务器配置一个“虚拟”接口,该接口具有 VIP 的 IP。同样,在 Red Hat/CentOS 上:

# cat /etc/sysconfig/network-scripts/ifcfg-dummy0
DEVICE=dummy0
BOOTPROTO=static
IPADDR=10.10.0.1
NETMASK=255.255.255.255
ONBOOT=yes
TYPE=Ethernet

arptable 规则将处理该 IP 的静默 ARP 请求(如果没有 arptables,所有真实服务器和负载均衡器将回答这个问题:谁拥有 10.10.0.1)。

我希望这有帮助!

相关内容