ailx10说:这篇是在2024年1月之前写的,后来又改过。刚接到大模型接口时,我发现一次普通 HTTP 请求要等好几秒,连着调用就慢得很明显。于是拿一百次请求做对照,把同步循环换成 aiohttp 并发,再分别整理 Python 3.6、3.7 和类封装的写法。这篇记录的是等待时间怎样逼着我去学异步。看到原来一条条排队的请求能重叠起来,才比较直观地理解了“不是每一步都在计算”这件事;后面的性能数字,也正是那组请求条件下跑出来的结果。
- 当次历史测试中,python3 http 同步请求100次,耗时接近102秒
- 当次历史测试中,python3 http 异步请求100次,不到6秒,在这组条件下耗时约为同步的十七分之一
当次历史测试中,python3 http 同步请求100次,耗时接近102秒

# python3 http 同步请求
import requests
import time
def fetch_data(url):
response = requests.get(url)
return response.text
def main():
url = 'http://ctf.hackbiji.top' # 我自己的网站
total_requests = 100 # 请求次数
start_time = time.time() # 记录开始时间
responses = [fetch_data(url) for _ in range(total_requests)]
end_time = time.time() # 记录结束时间
# 处理响应
for i, response in enumerate(responses[:5]):
print(f"Response {i + 1}...")
print(f"Total responses: {len(responses)}")
total_time = end_time - start_time
print(f"Total time taken: {total_time} seconds")
# 运行主函数
main()
当次历史测试中,python3 http 异步请求100次,不到6秒,在这组条件下耗时约为同步的十七分之一

示例是历史环境记录;请仅向获授权的测试服务发送请求,按当前 Python 与依赖版本核对兼容性,实际使用还需限制并发、设置超时和处理异常。
python3.7版本
# python3.7 http 异步请求
import asyncio
import aiohttp
import time
async def fetch_data(session, url):
async with session.get(url) as response:
return await response.text()
async def main():
url = 'http://ctf.hackbiji.top' # 我自己的网站
total_requests = 100 # 请求次数
async with aiohttp.ClientSession() as session:
tasks = []
for _ in range(total_requests):
task = asyncio.create_task(fetch_data(session, url))
tasks.append(task)
start_time = time.time() # 记录开始时间
responses = await asyncio.gather(*tasks)
end_time = time.time() # 记录结束时间
# 处理响应
for i, response in enumerate(responses[:5]):
print(f"Response {i + 1}...")
print(f"Total responses: {len(responses)}")
total_time = end_time - start_time
print(f"Total time taken: {total_time} seconds")
# 运行主函数
asyncio.run(main())
python3.6版本
# python3.6 http 异步请求
import asyncio
import aiohttp
async def fetch_data(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return response.status, await response.text()
async def main():
url = 'http://ctf.hackbiji.top' # 我自己的网站
tasks = []
# 创建100个任务
for i in range(100):
task = asyncio.ensure_future(fetch_data(f"{url}"))
tasks.append(task)
# 并发执行任务
responses = await asyncio.gather(*tasks)
# 检查响应状态码
for i, (status_code, response_text) in enumerate(responses, 1):
if status_code == 200:
print(f"Request {i}: Request successful! Response ...") # 打印部分响应内容
else:
print(f"Request {i}: Request failed with status code: {status_code}")
# 运行异步函数
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
python3.6面向对象编程
# python3.6 http 异步请求
import asyncio
import aiohttp
class AsyncRequester:
def __init__(self, url):
self.url = url
async def fetch_data(self):
async with aiohttp.ClientSession() as session:
async with session.get(self.url) as response:
return response.status, await response.text()
async def make_requests(self, num_requests):
tasks = []
# 创建 num_requests 个任务
for i in range(num_requests):
task = asyncio.ensure_future(self.fetch_data())
tasks.append(task)
# 并发执行任务
responses = await asyncio.gather(*tasks)
# 检查响应状态码
for i, (status_code, response_text) in enumerate(responses, 1):
if status_code == 200:
print(f"Request {i}: Request successful! Response:...") # 打印部分响应内容
else:
print(f"Request {i}: Request failed with status code: {status_code}")
# 实例化类并运行
async def main():
requester = AsyncRequester('http://ctf.hackbiji.top') # 我自己的网站
await requester.make_requests(100) # 发送100个请求
# 运行异步函数
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
这次计时给的是当前样本的差异,不是并发越多就越快。会话复用、超时和异常都还要照顾,真正稳定的快,不应该只来自一次顺利完成的测试。
1036



被折叠的 条评论
为什么被折叠?



