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

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

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

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

从我的研究中,我想要实现的是所谓的“直接服务器返回”,这是负载均衡的常见设置。 它有时也被称为半反向代理

对于第4步,这听起来像我需要做MAC地址转换,然后将请求传回networking和服务器networking外的服务器将需要隧道。

对于第5步,我只需要configuration服务器B,根据负载平衡设置中的真实服务器。 也就是说,服务器B在回环接口上应该有服务器A的IP地址,并且不应该回答该IP地址的任何ARP请求。

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

我发现有很多硬件和软件可以在第4层进行简单的负载均衡,但这些解决scheme不足,无法处理我所需的自定义路由。 看来我需要推出我自己的解决scheme。

理想情况下,我想在Web服务器级别进行路由/转发,即在PHP或C#/ ASP.net中。 不过,我打算在Apache或IIS等较低级别上进行操作,或者在更低的级别上进行操作,即在所有操作之前使用自定义代理服务。

谢谢。

丹尼尔 – 你可以用LVS和一个集群文件系统来完成这个工作。 您的LVS负载均衡器将收到HTTP请求,并将请求转发给可响应请求的Web节点。 响应将直接离开networking节点,负载平衡器根本不会参与回复。

我把这个 (在Fedora上)的指导放在了虚拟化的Xen实例上。

我想,你应该使用caching代理服务器或HTTPredirect来实现你的目标。

例如,对于nginx,您可以使用后端(PHP脚本或一些FastCGI托pipe的服务器)来确定应该到哪个“数据中心”,并将X-Accel-Redirect返回到具有proxy_pass到该数据中心的新位置。 在这之后,nginx应该caching/存储你的结果。

所以,你在每个数据中心的configuration将只有100%本地文件不同。

第二种情况 – 后端以必要的直接链接返回301错误代码。

丹尼尔,你真的做完了你的功课。 也许有一个古鲁在那里certificate我错了,但我最初的回应是“不要那样做”。 我知道这是一个没有答案,但没有任何理由为什么你真的需要这个,这是我有最好的答案。 虽然我认为提出的解决scheme可以工作,但是为了隐藏一个域,处理很多configuration和设置 – 对我来说这太脆弱和复杂了。

我会build议:

  • 玩谈判强硬,并谈判单一领域的要求。 真正解释这会增加复杂性和成本。 然后使用普通的HTTPredirect到每个服务器/站点。
  • 要么
  • 将所有数据复制到所有数据中心(DC)以实现冗余。 使用Anycast在多个DC上创build一个域。 在每个DC上使用您select的传统负载均衡器。

HTH

任何商业负载平衡器都可以configuration为直接服务器返回。 (F5 BIG-IP可以做到这一点;在他们的术语中,它被称为“nPath路由”)。一个低成本的解决scheme是Linux虚拟服务器。 直接路由设置logging在这里 。

但是,问题在于,为使负载平衡对第3层透明,转发必须在第2层完成。这意味着您的负载均衡器和内容服务器必须位于相同的物理段上。 我不确定如何在几个数据中心完成这个任务。

或者,您可以HTTPredirect包含Flash应用程序的页面。 那么你会有独立的网站,每个都满足相同的原则。

Linux虚拟服务器和Keepalived的组合,也许一些arptable魔术应该完成你所追求的。 过去,我已经广泛地使用了这种方法,而且它被certificate是非常可扩展的。 真正的服务器在接收到连接之后与客户端进行对话的事实使负载均衡器(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 +)应位于同一networking上。

您还需要使用VIP的IP来为每个真实服务器configuration一个“虚拟”接口。 再次,在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)。

我希望这有帮助!

通过arp mangling和其他一些欺骗手段在本地执行DSR – 如果你想把这个扩展到一堆,我们称之为“从属”数据中心 – 你需要把这些数据包封装起来,然后发送到另一个盒子远程DC去除封装 – 可能是您的节点单独或它可能是另一个负载平衡器的常规做基于arp的DSR。

如果跨越多个数据中心进行此操作,则还需要确保其过滤function允许来自不pipe理的IP地址的传出stream量,并且可能基于stream量的任何防火墙设备都不是会干涉 – 因为他们只会看到谈话的一方(另一方进入封装)

只是一个补充 – 你能提供一些洞察你为什么需要这个特定的设置? 你到底在做什么,而不是使用redirect或多个域名。 如果实际的资源文件有多个域名可以使用,CDN或Anycast解决scheme将是一个更为经济和可靠的解决scheme – 让您的应用逻辑确定将用户redirect到哪个资源。

你所提出的技术上是有趣的,但它也造成了一个单一的失败点 – 如果你难以通过arp欺骗在本地二层进行parsing,那么在全球范围内处理它只会是更复杂….一个CDN 可能是你需要的。

这就是说 – 从纯粹的networking观点来看,这真的很有趣 – 如果你可以提供更多的细节,我可以使用Linux工具来制定一个特定的解决scheme,它可以完成你所要求的 – 听起来很有趣。

我不能放弃“相同的域名”的要求,不想去高级的networking路线,也许你可以放弃“在不同的位置存储不同的文件”的要求?

如果您可以让所有服务器(位置)存储所有文件,则可以在单个域后面的循环IP后面configuration相同的堆栈。 每个位置都将完全有能力并且可以在单个域后面访问。 当然,任何数据库操作仍然会带有复制或远程连接要求。

我在服务器和位置之间做了区分,因为在高速低延迟LAN上的反向代理并不是那么糟(参见Yorik的回答)。

应用程序请求路由怎么样?

http://www.iis.net/download/ApplicationRequestRouting

您的后端存储服务器可以使用DFS来保持您的内容在后台同步,并确保访问内容的服务器始终采用最短path访问内容。

丹尼尔,

解决方法应该在应用程序层。 如果您在较低层上执行此操作,则这些规则将适用于所有stream量,而在这里,这是针对特定应用程序的应用程序。

我build议你创build子域名,并将不同服务器的IP地址作为子域名Alogging。 因为它在同一个领域,第三方交易得到了照顾。 然后在中央服务器上使用数据库,并向特定服务器发出CURL请求。 这样,你的域名也是隐藏的,而你的应用程序工作。 但是,这里唯一的问题是数据库在任何时候都需要小心翼翼。 否则,你的申请将惨败。

确保数据库始终高效地运行。 您应该考虑制作一个备份数据库,以便您不必经历服务器停机时间的陷阱。

问候
Binaek Sarkar
基础