为什么没有水平可扩展软件负载均衡器平衡 SSL 的示例?

为什么没有水平可扩展软件负载均衡器平衡 SSL 的示例?

我对 ssl、本地会话和负载平衡有一系列的问题,它们似乎是相互关联的,因此我提前为这个问题的长度道歉。

我有一个使用基于文件的会话的网站。该网站的性质是大部分内容是 http,但有些部分是 ssl。目前,由于基于文件的会话,任何 ssl 请求都必须与任何先前的 http 请求到达同一服务器。

由于时间限制,我想做尽可能最简单的事情来平衡增加的 http 和 ssl 流量的负载。

粘性负载平衡算法似乎有两种选择:

  • 基于ip
  • 基于cookie

基于 IP 的解决方案可能会奏效,但当服务器停机或添加时,散列算法可能会改变用户访问的服务器,这对于当前基于文件的会话设置来说是不可取的。我还认为,从技术上讲,用户可以在浏览网站时合法更改 IP。

基于 cookie 的算法似乎更好,但是在使用 ssl 加密时无法检查 cookie 似乎存在自身的问题。

我一直在 Google 上搜索有关如何对 SSL 进行负载平衡的示例,但似乎找不到任何明确的设置示例,这些示例可以执行基于 cookie 的负载平衡,并且可以通过添加另一个 SSL 解码器来处理增加的 SSL 负载。

我见过的大多数明确示例都将 SSL 解码器(通常是硬件、apache_mod_ssl 或 nginx)置于浏览器客户端和负载均衡器之间。这些示例通常似乎有类似这样的内容(修改自http://haproxy.1wt.eu/download/1.3/doc/architecture.txt):

      192.168.1.1 192.168.1.11-192.168.1.14
 -------+-----------+-----+-----+-----+
        | | | | |       
     +--+--+ +-+-+ +-+-+ +-+-+ +-+-+    
     | LB1 | | 一 | | 乙 | | 丙 | | 丁 |    
     +-----+ +---+ +---+ +---+ +---+    
     Apache 4 廉价网络服务器
     mod_ssl
     哈普罗西

上述示例中的 ssl 解码部分似乎是一个无法水平扩展的潜在瓶颈。

我研究过 haproxy,它似乎有一个“mode tcp”选项,可以允许这样的操作,这样你就可以拥有多个 ssl 解码器:

              哈普罗西
                 |
            -------------
            | |
ssl-解码器-1 ssl-解码器2
            | |
        -------------------
        | | |  
      网络1 网络2 网络3

然而,在这样的设置中,你似乎会丢失客户端 IP,因为 haproxy 没有解码 ssl: https://cloud-support.engineyard.com/discussions/problems/335-haproxy-not-passing-x-forwarded-for

我也研究过 nginx,但我也没有看到任何水平可扩展的 ssl 解码器的明确示例。似乎有很多人将 nginx 视为潜在瓶颈的例子。至少这个链接似乎表明 nginx 甚至没有类似 haproxy 的设置选项,在这种情况下,您会因为说 nginx“不支持透明地将 TCP 连接传递到后端”而丢失 ip如何通过 nginx 代理传递 Apache SSL 流量?

问题:

  • 为什么似乎没有更多设置添加更多 SSL 解码器来处理增加的流量的例子?
  • 是不是因为ssl解码步骤只是理论上的瓶颈,实际上除了流量很大的网站外,一个解码器基本上就足够了?
  • 我想到的另一种可能的解决方案是,任何有如此多 SSL 需求的人可能也有一个集中式会话存储,因此客户端在连续请求中访问哪个 Web 服务器并不重要。然后您可以在每个 Web 服务器上启用 mod_ssl 或等效项。
  • 上面提到的 haproxy 解决方案似乎有效(除了客户端 IP 问题),但是否有人遇到过基于粘性 cookie 的软件负载平衡器解决方案,该解决方案可以通过增加解码器的数量同时保持客户端 IP 来实现,或者这在技术上是不可能的(因为您必须解码请求才能获得客户端 IP,在这种情况下,我们有一个解码器瓶颈)。

假设我所说的一切都是真的,那么我的选择如下:

  • 使用 IP 哈希(对于可能合法更改 IP 的用户以及服务器添加和删除场景不利)
  • 使用 nginx 或 mod_ssl 作为第一个接触 SSL 请求的程序,这将是潜在的 SSL 解码瓶颈
  • 使用 haproxy 作为第一个接触 SSL 请求的程序,获得水平 SSL 可扩展性,但在 Web 服务器级别没有为 SSL 请求记录任何 IP(可能暂时没问题)
  • 从长远来看,应该转向移动或集中式会话存储,这样就不再需要粘性会话

答案1

严肃地说,“最简单的事情”是转移到集中式会话存储。您必须使用负载平衡器、haproxy、SSL 和其他程序来设置所有这些管道,而我见过的每一段会话处理代码都使得插入不同的存储引擎变得几乎微不足道,因此,只需一点代码和非常非常少的额外复杂性就可以解决您的所有问题。

答案2

womble 说得对,共享会话存储让所有事情都变得更容易。除了他的回答之外,我还可以稍微扩展一下这个问题的负载平衡部分:

为什么似乎没有更多设置添加更多 SSL 解码器来处理增加的流量的例子?

现代的多核 PC 可以处理数千个每秒 SSL 交易数。如果这成为瓶颈,那么来自F5、Citrix、Cisco 等的速度甚至更快。因此,大多数站点永远不会因为单设备 SSL 和负载平衡解决方案而变得无用。

假设我所说的一切都是真的,那么我的选择如下:

如果您需要的话,可以选择水平扩展 SSL 解密。

常见的做法是使用DNS Round Robin来实现高可用的SSL加速器对,即为域发布多个IP地址,每个IP地址指向一对SSL加速器。

在这种情况下,您可能会担心 DNS TTL 在用户会话中超时,从而将用户转移到另一台应用服务器。这种情况应该不常见,但确实会发生。共享会话存储是常见的解决方案,但也可以采用其他方式处理。

举个例子,你可以将 SSL 解密与应用服务器平衡分开。SSL 处理比基本负载平衡更耗费 CPU,因此单个负载平衡器应该能够满足几个 SSL 加速器的需求。就像这样:

Internet --> DNS round robin to multiple SSL accelerators --> plain HTTP to a single HTTP load balancer --> plain HTTP to multiple application servers

正如开头所提到的,共享会话存储简化了很多事情,而且几乎肯定是一个比在 SSL/负载平衡层中增加很多复杂性更好的长期解决方案。

答案3

当产品不断发展时,回答这类 2 年前的问题很有趣。目前,haproxy 支持 PROXY 协议,即使在纯 TCP 模式下,它也允许它将客户端的 IP 传递到下一跳。如果您想将其用作 SSL 场(可能由 haproxy 服务器构成)前面的第一层,它还支持本机 SSL 以及 SSL 粘性。所以看起来你的请求有点超前,而且实施已经赶上来了 :-)

答案4

一些随机想法 ;)

首先,枪毙那个决定使用基于文件的会话数据的人。从文件系统读取/写入数据绝对不会比直接返回源来提取所需数据更快。这是最糟糕的做法。

我个人从未见过在会话中存储数据比在必要时直接从数据库中提取数据更好的情况。尽管如此,我见过使用 memcache 或类似的缓存策略可以帮助网站扩展到数百万用户,但这与使用会话甚至不是一回事。

其次,您刚刚发现了根本不使用会话的首要原因:负载平衡。仅供参考 - 粘性并不意味着卡住。即使启用了粘性会话,您也很有可能在使用您的应用程序的过程中将用户转移到另一台服务器。这种情况会在最不合时宜的时候发生。粘性只是意味着负载平衡器将尝试将用户推回到他们开始所在的服务器,但这绝不是一种保证。

这一点通常会导致人们将会话存储回数据库中……我认为这是完整的失败。要使会话正常工作,必须在每次页面请求时加载和写入会话。当会话存储在数据库中时(对于负载平衡服务器而言是必需的),这需要两次服务器查询:第一次查询用于获取数据,第二次查询用于写入任何更新。

失败的部分是人们通常使用会话,所以他们不必返回数据库来提取用户名之类的东西......但是如果页面必须查询数据库来加载会话那么......好吧,你应该能够在这里看到逻辑问题。

会话的情况更糟……因为页面处理器必须在页面生命周期结束时将会话数据写回数据库……以防发生任何变化。这意味着,对于每次页面加载,您最终都会有两个查询来获取该用户的名称,而不是一个查询。此外,这意味着序列化和反序列化数据,这本身也会对性能产生影响。

我的观点是:会话是邪恶的,没有它通常更好。仅在一个 Web 服务器上运行的低流量站点不需要可能发生的性能提升;而在 Web 场上运行的高流量站点由于它而限制了扩展。

相关内容