HTTP2:不同的域但相同的IP,多个连接或一个连接?

时间:2018-02-09 08:36:23

标签: linux http nginx web http2

在HTTP2中:

因此,当请求一个带有多个域(www.example.com,api.example.com ...)的html页面时,会有多个连接。

但是如果这些域共享一个相同的IP呢?还有多个连接吗?

3 个答案:

答案 0 :(得分:6)

这取决于客户。

http://httpwg.org/specs/rfc7540.html#HttpExtra

  

客户端不应该打开与给定主机和端口对的多个HTTP / 2连接,其中主机派生自URI,选定的替代服务[ALT-SVC]或配置代理。

     

...

     

客户端 MAY 使用不同的服务器名称指示[TLS-EXT]值打开到同一IP地址和TCP端口的多个连接,或者提供不同的TLS客户端证书,但应该避免与相同的配置。

     

...

     

直接或通过使用CONNECT方法创建的隧道(第8.3节), MAY 对原始服务器的连接可以重用于具有多个不同URI权限组件的请求。只要原始服务器具有权威性,就可以重用连接(第10.1节)。对于没有TLS的TCP连接,这取决于主机已解析为相同的IP地址。

所以没有真正的硬性要求,所以如果客户有很好的理由建立多个连接而不是重用,那么就可以这样做。

特别是如果两个域都使用不同的TLS证书(不是两个名称都作为SubjectAltNames存在的证书),我希望每个域都能看到一个单独的连接。

答案 1 :(得分:3)

正如@mata所说,这取决于客户。

然而,一个明确的用例是连接合并。

在HTTP / 1.1域下经常进行分片(例如,www.example.com也可能有一个static.example.com域用于提供静态资产)。这有两个原因:

  1. 打破浏览器经常使用的每个域的6-8连接限制,并允许更多并行下载。
  2. 拥有所谓的“无cookie”域,这节省了为不需要它们的静态资产发送这些HTTP标头的开销(例如图像,css,javascript)。
  3. 在HTTP / 2下有一个连接,并行下载的限制是流限制,它要高得多(通常为100-150,但也可以是无限制的)。此外,通过HPACK标头压缩,大型cookie可以降低性能(尽管仍然存在安全问题,这可能是无cookie域的另一个原因)。

    那么,我们现在应该完全放弃分片域吗?那些不支持HTTP / 2的客户端呢?虽然支持非常好,但它不是通用的,代理连接背后的那些(例如公司连接或防病毒软件)通常也不能使用它,即使它们的浏览器可以。

    浏览器使用连接合并功能将相同的连接(通常是那些具有相同IP地址和相同TLS证书的连接)折叠到一个连接中,而不是在使用HTTP / 2时打开一个连接并允许HTTP / 1.1连接继续查看这些作为单独的域。 Daniel Haxx has the best blog post on how this is actually implemented by browsers(虽然在撰写本文时大约有一年半的时间,所以这可能已经改变了)。总而言之,Chrome正如您所期望的那样使用它,Firefox(过度?)积极地在尽可能多的情况下进行合并(可能还有一些它不应该!)并且Edge和Safari不会合并所有

    如果连接在不应该合并时,服务器可以使用421 HTTP状态代码进行响应,这基本上意味着“你在做什么,这不是对我的请求!!”然后浏览器可以通过单独的连接重试。

    看起来HTTP / 2似乎会很快添加ORIGIN Frame,这将允许服务器响应任何请求,“嘿,如果你愿意,我也可以为你提供api.example.com请求”风格的消息。即使IP地址不匹配(有些人担心security implications of that!)。

    虽然我们讨论的是主题,但并不总是这样,因为单个域也会始终使用一个连接。阅读Jake Archibald's excellent post on HTTP/2 Push,表明存在各种情况(不是这种情况)(总结为:对于非凭证请求,在Edge中的单独选项卡中打开相同的域,或者甚至在Safari的同一选项卡上随机打开) )。

答案 2 :(得分:0)

我们遇到了这个问题

在负载均衡器后面的不同服务器上使用多个环境进行测试设置

  • test1.domain
  • test2.domain
  • testx.domain

例如从 test1.domain.com 切换到 test2.domain.com 出现 404 错误或未授权

出现此问题是因为负载均衡器希望客户端添加包含主机名的 SNI 扩展,例如test1.domain.com

在第一次调用负载均衡器时,包含SNI名称,随后chrome浏览器指向另一个环境test2.domain.com,chr​​ome不发送SNI扩展名test2.domain.com,因此流量仍然路由 test1.domain.com

由于持有 test1.domain.com 的服务器不知道 test2.domain.com,因此向 chrome 发送 404 返回。

要么负载均衡器上的每个服务都必须重新配置为自己的 IP 地址,要么需要执行返回代码 421。 见https://daniel.haxx.se/blog/2016/08/18/http2-connection-coalescing/ 部分:惊喜和减轻它们的方法(HTTP 状态码 421 的实现)