使用Python Cloud Vision API时遇Too many open files错误求助
解决Google Cloud Vision API "Too many open files" 错误
首先得明确:这个错误本质是你的Python进程打开的文件描述符(包括实际文件、网络套接字等资源)数量超过了系统限制,urllib3只是触发错误的环节——因为它要新建HTTPS连接(套接字也算文件描述符)时,发现没有可用的描述符了。结合你的场景和代码,我给你一步步拆解问题和解决方案:
一、先快速临时缓解:调整系统文件描述符限制
Ubuntu默认给进程的软文件描述符限制是1024,批量处理大量图片+频繁的API请求很容易耗尽这个数:
- 临时调整:在启动脚本的终端里先执行
ulimit -n 4096,把当前shell的软限制调高到4096,再运行你的Python脚本。 - 永久生效:编辑
/etc/security/limits.conf,添加两行(替换成你的用户名):
保存后重新登录终端,限制就会生效。your_username soft nofile 4096 your_username hard nofile 10240
二、代码优化:减少不必要的资源占用
这是解决问题的核心,你的代码目前有几个潜在的资源浪费点:
1. 复用Vision客户端实例
不要在循环处理每张图片时创建新的vision.ImageAnnotatorClient()!这个客户端会管理底层的HTTP/GRPC连接池,每次新建都会导致大量未释放的连接占用文件描述符。正确的做法是在循环外只创建一次:
def main(): args = get_commandline_args() # 关键:只初始化一次客户端,所有图片复用这个实例 client = vision.ImageAnnotatorClient() image_paths = list(Path(args.image_dir).glob('*.jpg')) # 处理debug模式的限制 if args.debug: image_paths = image_paths[:3] with open(args.output_path, 'w', newline='') as csvfile: writer = csv.writer(csvfile) writer.writerow(['image_path', 'labels']) for path in image_paths: img = load_image(str(path)) # 用同一个客户端调用API response = client.label_detection(image=img, max_results=args.max_results) labels = [label.description for label in response.label_annotations] writer.writerow([str(path), ','.join(labels)])
2. 补全截断的代码
你提供的detect_labels_of_image函数明显没写完(_path = Pat这里是截断了),要确保函数逻辑完整,且不要在函数内部重复创建客户端。比如完整的函数可以写成:
def detect_labels_of_image(path, max_results, client): img = load_image(path) response = client.label_detection(image=img, max_results=max_results) return [label.description for label in response.label_annotations]
三、升级依赖包
你的google-cloud-vision版本是0.31.1,这是2018年的旧版本,存在不少连接管理的bug。升级到最新稳定版能直接解决很多底层资源泄漏问题:
pip install --upgrade google-cloud-vision
(升级后如果遇到API接口变化,可以参考官方文档调整,新版本的兼容性和稳定性会好很多)
四、排查剩余问题(如果还是报错)
如果调整后还是出现错误,可以用lsof -p $(pidof python3)命令查看你的Python进程当前打开的所有文件描述符,看看是哪些资源(比如大量未关闭的套接字、残留的文件句柄)在占用,再针对性修复。
内容的提问来源于stack exchange,提问作者katsuya
相关产品推荐
相关产品推荐

