Python 中的多线程 API 查询时出错
Error while multi threading API queries in Python
我在部署了开源路由机 (OSRM) 的服务器中执行查询。我发送了一组坐标并获得了街道网络上网络距离的 n x n 矩阵。
为了提高计算速度,我想使用“ThreadPoolExecutor”来并行化查询。
到目前为止,我以两种方式设置连接,都给我同样的错误:
def osrm_query(url_input):
'Send request'
response = requests.get(url_input)
r = response.json()
return r
def osrm_query_2(url_input):
'Send request'
s = requests.Session()
retries = Retry(total=3,
backoff_factor=0.1,
status_forcelist=[ 500, 502, 503, 504 ])
s.mount('https://', HTTPAdapter(max_retries=retries))
response = s.get(url_input)
r = response.json()
return r
我生成了一组 URL(在 _urls 列表中),我想将其作为请求发送并以这种方式并行化:
with ThreadPoolExecutor(max_workers=5) as executor:
for each in executor.map(osrm_query_2, _urls):
r.append(each)
到目前为止,一切正常,但是,当解析超过 40,000 个 URL 时,我收到此错误:
OSError: [WinError 10048] Only one usage of each socket address (protocol/networ
k address/port) is normally permitted
据我了解,问题是我从我的机器发送了太多请求,耗尽了可用于发送请求的端口数量(看起来这与我发送的机器无关请求)。
我该如何解决这个问题?
有没有办法告诉 treadPoolExecutor 重新使用连接?
我被 Stack Overflow 以外的人引导到正确的方向。
诀窍是将池中的工作人员指向请求会话。发送查询的函数 re-worked 如下:
def osrm_query(url_input, session):
'Send request'
response = session.get(url_input)
r = response.json()
return r
并行化为:
with ThreadPoolExecutor(max_workers=50) as executor:
with requests.Session() as s:
for each in executor.map(osrm_query, _urls, repeat(s)):
r.append(each)
通过这种方式,我将执行时间从 100 分钟(未并行化)减少到 7 分钟,其中 50 个工作人员作为 max_workers 参数,用于 200,000 个 url。
我在部署了开源路由机 (OSRM) 的服务器中执行查询。我发送了一组坐标并获得了街道网络上网络距离的 n x n 矩阵。
为了提高计算速度,我想使用“ThreadPoolExecutor”来并行化查询。
到目前为止,我以两种方式设置连接,都给我同样的错误:
def osrm_query(url_input):
'Send request'
response = requests.get(url_input)
r = response.json()
return r
def osrm_query_2(url_input):
'Send request'
s = requests.Session()
retries = Retry(total=3,
backoff_factor=0.1,
status_forcelist=[ 500, 502, 503, 504 ])
s.mount('https://', HTTPAdapter(max_retries=retries))
response = s.get(url_input)
r = response.json()
return r
我生成了一组 URL(在 _urls 列表中),我想将其作为请求发送并以这种方式并行化:
with ThreadPoolExecutor(max_workers=5) as executor:
for each in executor.map(osrm_query_2, _urls):
r.append(each)
到目前为止,一切正常,但是,当解析超过 40,000 个 URL 时,我收到此错误:
OSError: [WinError 10048] Only one usage of each socket address (protocol/networ
k address/port) is normally permitted
据我了解,问题是我从我的机器发送了太多请求,耗尽了可用于发送请求的端口数量(看起来这与我发送的机器无关请求)。
我该如何解决这个问题? 有没有办法告诉 treadPoolExecutor 重新使用连接?
我被 Stack Overflow 以外的人引导到正确的方向。
诀窍是将池中的工作人员指向请求会话。发送查询的函数 re-worked 如下:
def osrm_query(url_input, session):
'Send request'
response = session.get(url_input)
r = response.json()
return r
并行化为:
with ThreadPoolExecutor(max_workers=50) as executor:
with requests.Session() as s:
for each in executor.map(osrm_query, _urls, repeat(s)):
r.append(each)
通过这种方式,我将执行时间从 100 分钟(未并行化)减少到 7 分钟,其中 50 个工作人员作为 max_workers 参数,用于 200,000 个 url。