0

我用 python 对 http1.1/http2 做了一些基准测试,代码很简单,就像多次重复谷歌搜索请求一样。结果很有趣:http2 版本的速度要慢得多。(我尝试了两个 pycurl/httpx 库)有人可以解释为什么会发生这种情况吗?

更新:这是httpx版本代码:(第一pip install httpx[http2]

import time
import httpx
client = httpx.Client(http2=True)
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)
4

2 回答 2

0

https://github.com/dalf/pyhttp-benchmark可能会有所帮助。

看:

TLDR:使用 httpx,使用 http2 时

  • 避免大内容(> 64kb)。
  • 避免顺序请求
  • 更喜欢并行请求
于 2021-06-07T18:49:55.963 回答
0

因此,了解 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 协议本身无关。

于 2021-06-05T07:40:54.220 回答