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

如何解决google-maps-services-python并发调用的连接池限制问题?

问题:google-maps-services-python并发调用static_map效率低下及连接池警告

我尝试用google-maps-services-python库的static_map方法,结合concurrent.futures.ThreadPoolExecutor实现并发调用,但即便设置了较大的max_workers,并行执行效率仍未达到预期,还收到如下警告:

WARNING:urllib3.connectionpool:Connection pool is full, discarding connection: maps.googleapis.com. Connection pool size: 10

根据Google官方文档,静态地图API最高支持30000 QPM(每分钟查询数),理论上可进行大量并行调用。我想了解是否能通过该库实现高效并发,还是应直接调用静态地图API的URL(https://maps.googleapis.com/maps/api/staticmap?parameters)而非使用该库,以下是我的相关代码:

import googlemaps
import concurrent.futures

client = googlemaps.Client(key='<MYKEY')

# addresses = [ list of addresses to search with Google Maps API ]
images_path = 'images/'

def download_google_maps(filename, address):
  filename = filename + '.png'
  f = open(filename, 'wb')
  for chunk in client.static_map(size=(600, 600),
                                center=address,
                                zoom=20,
                                format="png"):
      if chunk:
          f.write(chunk)
  f.close()
  message = 'Got Google Maps image in ' + filename
  print(message)
  return message

def download_images(index, address):
    filename = images_path + str(index)
    download_google_maps(filename, address)

with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
    futures = []
    for i in range(len(addresses)):
        futures.append(executor.submit(download_images, i, addresses[i]))

    for future in concurrent.futures.as_completed(futures):
        try:
            result = future.result()
        except Exception as e:
            print(f'Exception: {e}')
解决方案

1. 调整客户端连接池大小

警告的根源是googlemaps库底层依赖的requests默认连接池大小只有10,当你开20个线程时,连接池不够用就会丢弃新连接。可以通过自定义session来修改连接池参数:

import googlemaps
from requests.adapters import HTTPAdapter

# 创建自定义session,设置更大的连接池
session = googlemaps.Client._create_session()
# pool_maxsize设为和max_workers一致或更大,比如50
adapter = HTTPAdapter(pool_connections=50, pool_maxsize=50)
session.mount("https://", adapter)

# 用自定义session初始化客户端
client = googlemaps.Client(key='<MYKEY>', session=session)

这样连接池就能匹配你的线程数,避免连接被丢弃,直接提升并发效率。

2. 优化代码细节

  • 用with语句管理文件,自动关闭,比手动调用close()更安全简洁:
def download_google_maps(filename, address):
    filename = filename + '.png'
    with open(filename, 'wb') as f:
        for chunk in client.static_map(size=(600, 600),
                                      center=address,
                                      zoom=20,
                                      format="png"):
            if chunk:
                f.write(chunk)
    message = f'Got Google Maps image in {filename}'
    print(message)
    return message
  • 用executor.map简化任务提交代码,不用手动循环创建futures:
with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
    # 直接把index和address对应传入,自动分发任务
    results = executor.map(download_images, range(len(addresses)), addresses)
    for result in results:
        try:
            print(result)
        except Exception as e:
            print(f'Exception: {e}')

3. 是否需要直接调用API URL?

完全没必要。googlemaps库已经帮你处理了参数编码、密钥管理、请求重试等繁琐细节,调整连接池后就能实现高效并发。直接调用URL反而需要自己处理这些逻辑,容易出现参数错误、签名问题或者重试机制缺失的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 21:45:29