Python中有许多HTTP客户端。使用最广泛且最容易的是requests。

持续连接

持续连接是自HTTP 1.1以来的标准,尽管许多应用程序并未使用它们。以简单模式使用请求时(例如使用get函数),连接会在返回时关闭,Session对象允许重用已经打开的连接。

import requests

session = requests.Session()

session.get("https://china-testing.github.io/")

# Connection is re-used

session.get("https://china-testing.github.io/")

每个连接都存储在连接池中(默认为10)

import requests

session = requests.Session()

adapter = requests.adapters.HTTPAdapter(

pool_connections=100,

pool_maxsize=100)

session.mount('http://', adapter)

response = session.get("http://example.org")

重用TCP连接有许多性能优势:

降低CPU和内存使用率(同时打开的连接较少)。

减少了后续请求中的延迟(无TCP握手)。

可以引发异常而不会关闭TCP连接。

HTTP协议还提供了流水线,流水线化允许在同一连接上发送多个请求,而无需等待答复(批处理)。不幸的是,请求库不支持此功能。但是,流水线请求可能不如并行发送它们那么快。实际上,HTTP 1.1协议强制以与发送请求相同的顺序发送答复-先进先出。

并行

requests的主要缺点是同步的。调用requests.get("http://example.org")会阻塞程序,直到HTTP服务器完全答复为止。可以通过使用并发线程提供的线程池来缓解此问题。它允许以非常快速的方式并行化HTTP请求。

from concurrent import futures

import requests

with futures.ThreadPoolExecutor(max_workers=4) as executor:

futures = [

executor.submit(

lambda: requests.get("http://example.org"))

for _ in range(8)

]

results = [

f.result().status_code

for f in futures

]

print("Results: %s" % results)

也可以借助requests-futures的库:

来自requests_futures导入会话

from requests_futures import sessions

session = sessions.FuturesSession()

futures = [

session.get("http://example.org")

for _ in range(8)

]

results = [

f.result().status_code

for f in futures

]

print("Results: %s" % results)

在请求中使用期货

默认情况下,创建具有两个线程的工作程序,但是程序可以通过将max_workers参数甚至是自己的执行程序传递给FuturSession对象来轻松自定义此值,例如:FuturesSession(executor=ThreadPoolExecutor(max_workers=10))。

异步

如前所述,请求是完全同步的。这会在等待服务器回复时阻止应用程序,从而降低程序速度。在线程中发出HTTP请求是一种解决方案,但是线程确实有其自身的开销,这暗示着并行性,这并不是每个人总是很高兴在程序中看到的东西。

从版本3.5开始,Python使用异步将异步作为其核心。aiohttp库提供了一个基于asyncio之上的异步HTTP客户端。该库允许按顺序发送请求,但无需等待答复回来再发送新请求。与HTTP流水形成对比,aiohttp通过多个连接并行发送请求,避免了前面解释的排序问题。

# Author: 钉钉或微信pythontesting 技术支持qq群:630011153 144081101

import aiohttp

import asyncio

async def get(url):

async with aiohttp.ClientSession() as session:

async with session.get(url) as response:

return response

loop = asyncio.get_event_loop()

coroutines = [get("https://china-testing.github.io/") for _ in range(8)]

results = loop.run_until_complete(asyncio.gather(*coroutines))

print("Results: %s" % results)

所有这些解决方案都提供了不同的方法来提高HTTP客户端的速度。

性能

下面的代码向HTTPbin.org发送请求。本示例实现了上面列出的所有技术并对它们进行计时。

# Author: 钉钉或微信pythontesting 技术支持qq群:630011153 144081101

import contextlib

import time

import aiohttp

import asyncio

import requests

from requests_futures import sessions

URL = "http://httpbin.org/delay/1"

TRIES = 10

@contextlib.contextmanager

def report_time(test):

t0 = time.time()

yield

print("Time needed for `%s' called: %.2fs"

% (test, time.time() - t0))

with report_time("serialized"):

for i in range(TRIES):

requests.get(URL)

session = requests.Session()

with report_time("Session"):

for i in range(TRIES):

session.get(URL)

session = sessions.FuturesSession(max_workers=2)

with report_time("FuturesSession w/ 2 workers"):

futures = [session.get(URL)

for i in range(TRIES)]

for f in futures:

f.result()

session = sessions.FuturesSession(max_workers=TRIES)

with report_time("FuturesSession w/ max workers"):

futures = [session.get(URL)

for i in range(TRIES)]

for f in futures:

f.result()

async def get(url):

async with aiohttp.ClientSession() as session:

async with session.get(url) as response:

await response.read()

loop = asyncio.get_event_loop()

with report_time("aiohttp"):

loop.run_until_complete(

asyncio.gather(*[get(URL)

for i in range(TRIES)]))

运行此程序将给出以下输出:

Time needed for `serialized' called: 12.12s

Time needed for `Session' called: 11.22s

Time needed for `FuturesSession w/ 2 workers' called: 5.65s

Time needed for `FuturesSession w/ max workers' called: 1.25s

Time needed for `aiohttp' called: 1.19s

image.png

使用Session对象并因此重新使用连接意味着节省了8%的时间。

如果您的系统和程序允许使用线程,那么最好使用它们来并行化请求。但是,线程有一些开销,而且不是轻量级的。他们需要创建,启动然后加入。

除非您仍在使用旧版本的Python,否则如果您想编写一个快速且异步的HTTP客户端,无疑使用aiohttp应该是当今的方式。它是最快,最具扩展性的解决方案,因为它可以处理数百个并行请求。替代方案是并行管理数百个线程不是一个好选择。

Streaming

另一个有效的速度优化是流式传输请求。发出请求时,默认情况下会立即下载响应的正文。请求库提供的流参数或aiohttp的content属性都提供了一种在执行请求后不立即将全部内容加载到内存中的方法。

import requests

# Use `with` to make sure the response stream is closed and the connection can

# be returned back to the pool.

with requests.get('http://example.org', stream=True) as r:

print(list(r.iter_content()))

用aiohttp流

import aiohttp

import asyncio

async def get(url):

async with aiohttp.ClientSession() as session:

async with session.get(url) as response:

return await response.content.read()

loop = asyncio.get_event_loop()

tasks = [asyncio.ensure_future(get("https://china-testing.github.io/"))]

loop.run_until_complete(asyncio.wait(tasks))

print("Results: %s" % [task.result() for task in tasks])

为了避免无用地分配可能的数百兆内存,不加载全部内容非常重要。如果您的程序不需要整体访问整个内容,而是可以处理块,那么最好使用这些方法。例如,如果您要保存内容并将其写入文件,则仅读取一个块并同时写入它将比读取整个HTTP正文(分配大量的内存)具有更高的内存效率。 然后将其写入磁盘。

我希望这可以使您更轻松地编写适当的HTTP客户端和请求。如果您知道任何其他有用的技术或方法,请随时在下面的评论部分写下来!

python 高性能http服务器_Python高性能HTTP客户端相关推荐

  1. python实现同一个服务器对应多个客户端进行通信

    本代码实现的功能为:服务器将客户端A发送的信息(json串)进行处理,并转发给客户端B. 客户端A的请求端口为19005,客户端B的请求端口为19004 具体实现功能代码如下: 1.客户端A向服务端发 ...

  2. 高性能运算服务器6,高性能运算力 纵观各家刀片式服务器(6)

    浪潮天梭TS10000刀片式服务器 浪潮天梭TS10000产品是浪潮天梭工程高端战略计划的产物,汇集业界最新的技术手段,以及浪潮十年来对服务器产业的理解,推出的适合于超大规模.超高性能科学计算应用的高 ...

  3. python搭建web服务器_Python搭建简单的web服务器

    Python搭建简单的web服务器 1.win+R输入cmd打开命令行 2.通过 cd 进入到你保存 HTML 文件的目录.例如:H:\D3\d3 输入 cd\ 指令进入到C盘的根目录.(CD(更改目 ...

  4. python实现web服务器_python实现web服务器

    本想写一篇关于http->nginx->php这个过程中数据是怎么传输的文章,想了半天,实在没有心情去写.刚好看了一下python,就想着用python实现一下web服务器的过程.这个很简 ...

  5. python实现web服务器_python实现静态web服务器

    HTTP协议简介 HTTP请求 1:浏览器首先向服务器发送HTTP请求,请求包括: 方法:GET还是POST,GET仅请求资源,POST会附带用户数据: 路径:/full/url/path: 域名:由 ...

  6. python 做网站用服务器_Python实现简单的Web服务器 Part2—支持动态网站

    1. 什么是CGI? CGI即通用网关接口(Common Gateway Interface),是外部应用程序(CGI程序)与Web服务器之间的接口标准,是在CGI程序和Web服务器之间传递信息的规程 ...

  7. python网络编程证书_python 网络编程——客户端

    网络通信的基本接口是socket,它扩展了操作系统的基本I/O到网络网络通信.socket可以通过socket()函数来建立,通过connect()函数来连接.得到了socket,可以确定本地和远程端 ...

  8. python批量巡检服务器_python批量服务器巡检

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  9. python socket通信 心跳_Python Socket 多客户端心跳监测 | kTWO-个人博客

    # coding:utf8 import socket import time import thread #接受心跳包 def get_hart(host, port): global clien_ ...

最新文章

  1. Seaborn使用lmplot函数可视化散点图并添加回归曲线以及回归线对应的置信区间(Scatter plot with regression line)
  2. 几条曲线构建Android表白程序
  3. 手机app 有没有window.location.href_热议小程序使用场景越来越多,未来有没有可能替代手机APP?...
  4. Spring Boot 配置文件中的花样,看这一篇足矣!
  5. DBUtils开源JDBC类库,对JDBC简单封装(作用是:简化编码工作量,同时不会影响程序的性能)...
  6. Mind Master Pro 8.0——安装教程
  7. Python list去重,去掉list中元素为字典的且字典部分key相同的list元素(列表去重、字典去重)
  8. 服务器双网卡设置安全_服务器的基础知识
  9. 计算机编程关键字一,和计算机编程有关的101条伟大的名言
  10. 管理感悟:工作管理的两大要点
  11. 用nodejs框架Ghost快速搭建自己的网站
  12. oracle12c下载安装
  13. 阿里云矢量图标使用方法
  14. note4x rom android p,红米Note4x安卓8.0刷机包
  15. 云服务器和真实服务器,个人网站主机选择原则 看配置也要看是不是有助于优化...
  16. 044. 使用 CDN 实现应用的缓存和加速
  17. Iphone X黑科技大揭秘,这几大摄像功能是要上天!
  18. Keras.layers.core.dense()方法详解
  19. 中国为什么产生不了Salesforce?
  20. ruby的DIR.pwd

热门文章

  1. 工业物联网卡未来发展的优势和特点
  2. android添加工程依赖工程,Android Studio为项目加上模块依赖的图文方法
  3. scrapy 中爬取时被重定向_Scrapy详解之scrapy shell
  4. AcWing 839. 模拟堆
  5. windows平台oracle自动job,oracle删除oem中自动备份job
  6. R语言︱非结构化数据处理神器——rlist包
  7. 区块链共识问题都有什么?
  8. java8-谓词(predicate)
  9. log.py——打印出独立IP,并统计独立IP数
  10. 存储基础(VG、LV、LP、PV、PP)