使用grequests发起10万次GET请求遇‘打开文件过多’错误求助
解决grequests发起大量请求时的"too many open files"错误
我之前批量处理10万级HTTP请求时也碰到过一模一样的问题!这个错误本质是系统文件描述符上限被耗尽了——每个HTTP请求都会占用一个套接字(对应一个系统文件描述符),grequests默认的并发量太高,瞬间就超过了系统允许的最大打开文件数限制。
下面是亲测有效的解决思路:
1. 限制grequests的并发请求数
grequests的map()方法支持通过size参数控制同时执行的请求数量,这是最直接有效的方法。建议把并发数限制在50-200之间(具体数值根据你的系统配置调整),避免一次性打开过多套接字:
# 调整map方法的size参数,限制并发数为50 responses = grequests.map(rs, size=50)
2. 分批处理请求
如果总请求数达到10万级,即使限制了并发数,长时间运行也可能积累资源占用。可以把请求分成多个批次,处理完一批再继续下一批,给系统足够的时间释放资源:
import grequests batch_size = 500 # 每批处理500个请求 with open("./100k-sites.csv", "r") as f: urls = ["http://" + line.rstrip() for line in f] for i in range(0, len(urls), batch_size): batch_urls = urls[i:i+batch_size] rs = (grequests.get(u, timeout=1) for u in batch_urls) # 限制每批的并发数为50 responses = grequests.map(rs, size=50) for r in responses: try: if r: # 这里写处理响应体的逻辑 # example: print(r.text[:100]) r.close() # 显式关闭响应,释放套接字资源 except Exception as e: # 可选:记录错误日志,方便排查问题 # print(f"处理请求出错: {e}") pass
3. 调整系统文件描述符限制(可选)
如果你的系统允许修改配置,可以临时或永久提高文件描述符的上限:
- 临时生效:在终端执行
ulimit -n 65535,该设置在终端关闭后失效 - 永久生效:修改
/etc/security/limits.conf文件,添加以下内容后重启系统或重新登录:
注意:这个操作需要管理员权限,且不是所有环境都允许修改系统配置,优先用前两种方法。* soft nofile 65535 * hard nofile 65535
4. 优化资源释放
确保每个响应处理完成后显式调用r.close(),避免套接字资源泄露。即使grequests会自动处理,显式关闭能更稳妥地释放资源,尤其是在异常场景下。
总结
最稳妥的方案是结合分批处理+限制并发数,既不需要修改系统配置,又能有效控制资源占用。如果还是遇到问题,再考虑调整系统文件描述符上限。
内容的提问来源于stack exchange,提问作者user8967637
相关产品推荐
相关产品推荐

