Requests 与 HTTP Keep-Alive

in #requests6 years ago

在半个月以前,我介绍过一个强大并且易于使用的Python HTTP 库:Requests,并且在文章中提及了Requests的会话(Session)中可以自动实现持久链接(Keep-Alive)。

但是古人教导我们纸上得来终觉浅,绝知此事要躬行,不实际演练一下,我总觉得不放心,于是写个小程序测试一下。

思路

我们做一些小程序,遍历获得几个用户的用户ID以及用户名。通过对比程序执行时间,来看看Keep-Alive是否生效。

其实这个是可以通过一个API一下子返回的,那么就一次连接岂不是无法彰显Keep-Alive的作用了,所以就用笨方法喽。

代码

import requests
import json
import time

users = ['lemooljiang', 'ace108', 'oflyhigh', 'deanliu', 'rivalhw']
rpc = "https://api.steemit.com"

start = time.time()
for user in users:
        payload = {"jsonrpc": "2.0", "method": "call", "params": ["database_api", "get_accounts", [[user]]], "id": 1}
        r = requests.post(rpc, data=json.dumps(payload).encode('utf-8'))
        json_r = json.loads(r.text)
        print("id:", json_r['result'][0]['id'], "\tname:", json_r['result'][0]['name'])
end =  time.time()
print("Execution Time: ", end - start)

session = requests.session()
start = time.time()
for user in users:
        payload = {"jsonrpc": "2.0", "method": "call", "params": ["database_api", "get_accounts", [[user]]], "id": 1}
        r = session.post(rpc, data=json.dumps(payload).encode('utf-8'))
        json_r = json.loads(r.text)
        print("id:", json_r['result'][0]['id'], "\tname:", json_r['result'][0]['name'])
end =  time.time()
print("Execution Time: ", end - start)

执行结果

以下为上述程序执行结果:

对比可知,使用Session程序效率大幅提高,这就是Keep-Alive的神奇之处哦。

尽管效率提升很明显,约2-3倍,但是没到很夸张的地步,比如10倍8倍,这是因为我们get_accounts取回的数据量很大,如果数据量很小,网络操作频繁的话,就会更加明显啦。

验证

你可能说,尽管效率提升了,但是一定是Keep-Alive的功劳吗?也许就是Session干了啥不为人知的提升效率的勾当呢?

我们在代码中加入如下语句来打印DEBUG信息

import logging
logging.basicConfig(level=logging.DEBUG)

我们把程序结果分成两部分截屏,便于比较

通过对比,我们很容易就发现如下规律:

  • 第一段程序每次都创建连接,再请求数据
  • 第二段程序仅创建一次连接,然后每次请求数据即可

并且我们捎带发现一个秘密,Requests用的urllib3哦。

结论

Requests的会话(Session)中可以自动实现持久链接(Keep-Alive),可以极大程度提升程序的效率,尤其是网络操作频繁的程序。

相关链接

Sort:  

自从用了 requests 之后, 就再也不碰 urllib 了 :P

Nyan pu arti ilee? Meutatupu tan

你的收入好多啊,请教怎么玩?我刚进入steemit,主要用来记录了

一直在用requests :P

Coin Marketplace

STEEM 0.20
TRX 0.14
JST 0.030
BTC 64170.07
ETH 3425.12
USDT 1.00
SBD 2.59