向 Google 地图地理编码 API 发送许多请求的正确方法是什么?

What is the proper way of sending many requests to Google Maps Geocoding API?

我的目标是将大量地址地理编码为 LatLng 对象。 我只能使用 Google,不能使用其他可能支持批量请求的 API。 因此,我必须使用 1 个请求 = 1 个地址,但我一直收到 OVER_QUERY_LIMIT。不确定这是怎么可能的,因为从 official docs 开始,我应该能够在客户端每秒对 50 个地址进行地理编码。

我的第一个想法是一次发出 50 个请求,等待所有请求 return,暂停一秒钟,然后继续接下来的 50 个地址...所以简化的代码看起来像这样:

const geocoder = new google.maps.Geocoder();
const allAddresses = [ /* 500 addresses */ ];
geocodeAddresses(allAddresses);

function geocodeAddresses(addresses) {
  const last50 = addresses.splice(-50);
  Promise.allSettled(
    last50.map((address) =>
      new Promise((resolve, reject) =>
        geocoder.geocode({
          address
        }, (results, status) => {
          console.log("Geocoded! Response: " + status);
          resolve();
        })))
  ).then(() =>
    setTimeout(() => geocodeAddresses(addresses), 1000)
  );
}

此代码一次成功 return 前 10 个请求,然后由于配额限制而在其他请求上失败(为什么?)。

所以我决定一次处理 1 个请求,每个结果后有 500 毫秒的延迟,这已经非常慢了。然后我会重复 OVER_QUERY_LIMIT 请求,超时为 2000 毫秒。结果很奇怪:

在大约 350 个完成的请求之后,每个请求都失败了 5-6 次,速度非常慢。似乎它可能呈指数级失败。

用 Google 对我的所有地址进行地理编码的最快方法是什么? 谢谢!

相关问题:

  • OVER_QUERY_LIMIT in Google Maps API v3: How do I pause/delay in Javascript to slow it down?

参见:

本节:

Managing errors and retries

If you get an OVER_QUERY_LIMIT status code as a response, you have exceeded the usage limits for the API. We recommend you try these usage optimization strategies.

Rate limits
The geocoding service is rate limited to 50 QPS (queries per second), calculated as the sum of client-side and server-side queries.

Web 服务的文档中有一个建议:Best Practices Using Google Maps APIs Web Services to use Exponential Backoff:

Exponential Backoff
In rare cases something may go wrong serving your request; you may receive a 4XX or 5XX HTTP response code, or the TCP connection may simply fail somewhere between your client and Google's server. Often it is worthwhile re-trying the request as the followup request may succeed when the original failed. However, it is important not to simply loop repeatedly making requests to Google's servers. This looping behavior can overload the network between your client and Google causing problems for many parties.

A better approach is to retry with increasing delays between attempts. Usually the delay is increased by a multiplicative factor with each attempt, an approach known as Exponential Backoff.