You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

测试场景下如何发送大量HTTP请求且无需等待响应?

嘿,这个问题我太熟了——同步阻塞的requests循环处理上万请求肯定慢得让人抓狂,毕竟每个请求都要等服务器响应完才会继续下一个。既然你完全不关心响应,那我们可以直接跳过等待响应的步骤,甚至不用建立完整的HTTP会话,直接把请求发出去就行。下面给你几个从快到慢(但复杂度也从高到低)的方案:

方案1:直接用Socket发送原始HTTP请求(最快,最底层)

因为我们不需要响应,所以只要把GET请求的字节流发出去,立刻关闭连接就行,不用等服务器回包。这种方式跳过了所有HTTP库的响应处理逻辑,效率拉满。

import socket
from concurrent.futures import ThreadPoolExecutor

def send_raw_request(url, param):
    # 手动解析URL,拆分主机和路径
    url_parts = url.split('://')[1].split('/')
    host = url_parts[0]
    path = '/' + '/'.join(url_parts[1:]) if len(url_parts) > 1 else '/'
    
    # 构建GET请求的参数字符串
    param_str = '&'.join([f"{k}={v}" for k, v in param.items()])
    # 组装完整的HTTP请求头
    request = (
        f"GET {path}?{param_str} HTTP/1.1\r\n"
        f"Host: {host}\r\n"
        "Connection: close\r\n\r\n"
    ).encode('utf-8')
    
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(0.5)  # 设置短超时,避免无意义的等待
        sock.connect((host, 80))  # HTTPS的话改端口为443,还要加SSL包装
        sock.sendall(request)
        sock.close()
    except Exception:
        # 不关心错误,直接忽略
        pass

def fire(urls, params):
    # 用线程池并发发送,IO密集型场景线程池能大幅提升效率
    with ThreadPoolExecutor(max_workers=50) as executor:
        for url in urls:
            for param in params:
                executor.submit(send_raw_request, url, param)

注:如果是HTTPS请求,需要用ssl.wrap_socket()对socket进行包装,会增加一点开销,但还是远快于requests。

方案2:用aiohttp异步发送,跳过响应读取

aiohttp是异步HTTP库,比同步requests高效得多,我们可以创建请求任务后立刻取消,完全跳过响应等待环节。

import asyncio
import aiohttp

async def send_async_request(session, url, param):
    try:
        # 创建请求任务,但不等响应就取消
        task = asyncio.create_task(session.get(url, params=param))
        task.cancel()
        await task
    except asyncio.CancelledError:
        # 捕获取消异常,直接忽略
        pass
    except Exception:
        pass

async def fire_async(urls, params):
    async with aiohttp.ClientSession() as session:
        tasks = []
        for url in urls:
            for param in params:
                tasks.append(send_async_request(session, url, param))
        # 并发执行所有任务,忽略异常
        await asyncio.gather(*tasks, return_exceptions=True)

def fire(urls, params):
    asyncio.run(fire_async(urls, params))

说明:异步模型在处理大量IO请求时,资源利用率比线程池更高,适合超大规模的请求场景。

方案3:用requests+线程池(最简单,改动最小)

如果你不想换库,只想在原有代码基础上提速,用线程池并发发送是最省心的方式,多个请求可以同时进行,不用逐个等待。

import requests
from concurrent.futures import ThreadPoolExecutor

def send_request(url, param):
    try:
        # 设置极短超时,开启stream模式避免读取响应内容
        requests.get(url, params=param, timeout=0.1, stream=True)
        # 直接结束,不处理响应
        return
    except Exception:
        pass

def fire(urls, params):
    with ThreadPoolExecutor(max_workers=100) as executor:
        for url in urls:
            for param in params:
                executor.submit(send_request, url, param)

说明:这个方案几乎是在你原有代码上做最小改动,线程池的并发能让速度比同步循环提升数倍。

总结

  • 追求极致速度选方案1,完全跳过HTTP库的冗余处理;
  • 想拥抱异步生态选方案2,资源利用率最高;
  • 想最小改动原有代码选方案3,省心省力。

内容的提问来源于stack exchange,提问作者Juicy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:14:33