因此,了解 HTTP/2 旨在解决什么以及不解决什么是很重要的。
HTTP/2 旨在通过向HTTP 协议添加多路复用来更高效地处理对同一站点的多个请求。基本上,HTTP/1.1 在请求进行时会阻塞整个连接,但 HTTP/2 不会——因此允许在此期间发出其他请求。
这意味着,单个请求(就像您正在做的那样)在 HTTP/2 下并不比在 HTTP/1.1 下更好。事实上,由于在每个 HTTP/2 连接开始时发送了一些额外的设置消息,它甚至可能会稍微慢一些,而这些消息在 HTTP/1.1 下是不需要的。虽然说实话,如果这种差异很明显,我很惊讶,那么你能详细说明一下有多慢吗?它还可能指向您正在使用的 HTTP/2 实现中效率较低的代码。可以分享一下代码吗?
即使在浏览器上下文中,如果您查看一个高度优化的网站,例如 Google 的主页(可能是互联网上访问量最大的页面,并且由一家非常了解网络以及如何优化网页的公司运营),那么您也可能看不出区别。谷歌主页基本上呈现在一个请求中,因为所有关键请求都被内联以使其尽可能快——无论是使用 HTTP/1.1 还是 HTTP/2。
然而,在浏览器中加载的典型页面涉及数十甚至数百个请求,HTTP/2 的优势通常非常明显。
如果你选择一个有很多小请求的极端站点(这是 HTTP/2 真正擅长的!),那么差异真的很明显。
*****编辑,看看你提供的好东西****
关于您的特定测试用例,我可以为 Google 重复此操作,但不能为其他站点重复此操作。
由于 HTTP/1.1 和 HTTP/2 的差异似乎太大了,所以我怀疑 HTTP/1.1 正在重用连接,但 HTTP/2 不是。将连接设置移动到 for 循环中会产生同样缓慢的结果,并且类似于之前的 HTTP/2 时间安排似乎证实了这一点。
import time
import httpx
start = time.time()
for _ in range(100):
client = httpx.Client(http2=True)
response = client.get("https://www.google.com/search?q=good")
response.raise_for_status()
print(time.time() - start)
同样,将 keepalives 更改为 0 也会减慢 HTTP/1.1 以匹配 HTTP/2:
client = httpx.Client(http2=False,limits=httpx.Limits(max_keepalive_connections=0))
Keepalive 在 HTTP/2 中不再是一个概念(连接默认保持活动状态,直到客户端认为不再需要保持活动状态)。
所以这似乎是 httpx 的 HTTP/1 处理的问题(他们确实注意到这是实验性的),而不是协议本身的问题。
最后转向这种代码风格,似乎使 HTTP/2 统计数据重新与 HTTP/1.1 保持一致:
import time
import httpx
with httpx.Client(http2=False) as client:
start = time.time()
for _ in range(100):
response = client.get("https://www.google.com/search?q=good")
response.raise_for_status()
print(time.time() - start)
但此时。429 Client Error: Too Many Requests...
谷歌对我向他们的服务器发送垃圾邮件并返回错误感到厌烦。
当我尝试在自己的服务器上重复相同的问题时,然后在 stackoverflow.com 上,我做不到 - HTTP/1.1 和 HTTP/2 的速度相似。如果相同的连接有助于加快速度,不确定谷歌是否在他们身边做一些缓存。
无论如何,重点是,这似乎是一个特定于实现的问题,与 HTTP 协议本身无关。