Google Places 出现 API 每日配额错误
结论
Premium plan web service requests per day: unlimited 只表示对应项目和服务的每日总量配额没有固定上限,不代表所有 Google Places 请求都不受限制。
如果 IAM & Admin 的 Quotas 页面显示 current usage 100%: 1,通常是实际请求命中了上限为 1 的配额指标,或者生产环境使用的 API key、Cloud 项目和控制台当前查看的项目并不一致。其他可能原因还包括 Places API 未启用、API key 限制配置错误、结算账号未真正绑定到请求所属项目,或短周期速率配额已经耗尽。
排查时不能只看 billing 是否显示有效。需要确认每次失败请求实际使用了哪个项目、哪个凭据和哪个 API,以及具体触发了哪项配额限制。
为什么 unlimited 仍会报配额错误
Google Maps Platform 同时使用多种配额和配置限制,包括:
- 每日请求配额
- 每分钟请求数
- 每分钟每用户请求数
- 特定 Places 服务的独立配额
- 手动设置的 quota override
- API key 所属项目的结算和 API 启用状态
- Premium Plan 旧凭据与普通 API key 对应的不同计费路径
任何一项实际生效的配额达到上限,都可能导致请求返回 OVER_QUERY_LIMIT,或出现类似提示:
You have exceeded your daily request quota for this API.
控制台中的 current usage 100%: 1 需要重点检查。它可能表示该指标的有效上限就是 1,而不是已经使用了一个所谓的无限配额。常见原因是误设了每日上限、配额调整没有应用到正确项目,或者当前查看的项目与生产 API key 所属项目不同。
部分 Google Maps API 会用相近的错误状态表示不同的配置问题。因此,即使错误文案提到每日配额,也不能据此断定请求量过大就是唯一原因。
排查步骤
1. 确认生产环境实际使用的凭据
不要只检查浏览器或服务器配置文件中原本打算使用的 key,要直接查看失败请求实际携带的凭据。
浏览器端可以在开发者工具的 Network 面板中检查 Maps JavaScript API 的加载地址,例如:
https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places
服务端 Web Service 请求可能类似:
https://maps.googleapis.com/maps/api/place/details/json?place_id=PLACE_ID&key=YOUR_API_KEY
检查生产环境是否仍在使用旧 key、测试项目的 key 或已经撤销的 key,也要确认环境变量加载失败时是否会回退到其他凭据。
API key 属于敏感凭据。排查期间不要把完整 key 写入日志或公开工单,最多保留脱敏后的前后几位。
2. 根据 API key 找到所属项目
在 Google Cloud Console 的 Credentials 页面找到该 key,并逐项确认:
- key 所属的 Cloud 项目
- 该项目是否就是当前查看 Quotas 的项目
- billing account 是否已绑定到该项目
- billing account 是否处于可计费状态
- 生产请求所需的 Places API 是否已在该项目启用
结算账号本身有效,不等于当前项目已经正确关联该账号,这两项需要分别核对。
如果使用 Maps JavaScript API 的 Places Library,需要检查相关的 Maps JavaScript API 和 Places 服务配置。如果服务器直接调用 Places Web Service,则要检查该请求实际对应的 Places API。新旧 Places 服务可能在控制台中显示为不同的 API,不能只根据相近的名称判断。
3. 检查具体的配额指标
进入实际项目的 API 配额页面,筛选生产请求使用的 API,然后逐项查看:
- Limit name
- Effective limit
- Current usage
- 是否存在自定义 quota override
- 是否有值为
1的每日或速率限制 - 是否同时存在按天、按分钟和按用户统计的指标
如果有效限制被设为 1,可以编辑或删除该自定义限制,让它恢复默认值,或者申请符合业务流量的额度。
修改配额后,配置可能需要一段时间才能在所有请求路径上生效。不要通过连续高频重试来验证修改结果。
4. 检查 API key 限制
API key 通常有两类限制:
- Application restrictions:HTTP referrers、IP addresses、Android apps 或 iOS apps
- API restrictions:允许该 key 调用哪些 API
浏览器端 key 需要确认生产域名已加入 HTTP referrer 允许列表,例如:
https://example.com/*
https://www.example.com/*
服务端 key 如果使用 IP 限制,应填写实际的对外出口 IP,而不是服务器内网地址。
还要确认 API restrictions 包含请求实际调用的 API。不要为了排查而长期保留 unrestricted key。可以短暂使用受控的测试凭据定位问题,确认原因后立即恢复最小权限限制。
5. 查看完整错误响应
Places Web Service 的 JSON 响应通常包含状态和附加错误信息。应记录经过脱敏的完整响应,不要只保留页面展示的通用提示:
{
"status": "OVER_QUERY_LIMIT",
"error_message": "You have exceeded your daily request quota for this API."
}
如果使用 Maps JavaScript API,也要查看浏览器控制台是否同时出现其他错误,例如 key 无效、API 未授权、来源域名不在允许范围内或 billing 配置异常。与通用提示同时出现的具体错误,通常更有助于定位问题。
6. 检查请求突增和重复调用
即使每日配额显示为 unlimited,短时间内的请求速率仍可能超限。可以重点检查:
- 输入框是否在每次
keyup时立即发起请求 - 同一组件是否被重复初始化
- 页面重渲染后是否重复绑定监听器
- 前端重试是否没有退避机制
- 机器人或爬虫是否触发了自动补全请求
- 服务端是否反复请求同一个地点的详情
Places Autocomplete 应使用防抖,并在适用时复用 session token。下面的示例只演示如何避免每次按键都触发业务逻辑,具体调用方式应与当前使用的 Places API 版本一致:
function debounce(fn, delay) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
}
const handlePlaceInput = debounce((value) => {
if (value.trim().length < 3) {
return;
}
// 在这里发起 autocomplete 请求
}, 300);
document.querySelector("#address").addEventListener("input", (event) => {
handlePlaceInput(event.target.value);
});
服务端遇到短周期限流时,可以对允许重试的请求使用指数退避,但不要对已经确定的每日配额或配置错误无限重试:
async function requestWithBackoff(request, maxAttempts = 4) {
for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
const response = await request();
if (response.ok) {
return response;
}
if (response.status !== 429 || attempt === maxAttempts - 1) {
throw new Error(`Request failed with HTTP ${response.status}`);
}
const delay = Math.min(1000 * 2 ** attempt, 8000);
await new Promise((resolve) => setTimeout(resolve, delay));
}
}
部分 Places 接口会返回 HTTP 200,再通过 JSON 中的 status 表示请求失败,因此不能只检查 HTTP 状态码。
快速定位方法
可以创建一个临时且限制严格的测试 key,并确认它满足以下条件:
- 位于已正确绑定 billing 的目标项目
- 只允许调用所需 API
- 仅允许生产域名或固定测试 IP
- 没有值为
1的自定义配额
如果同一请求换用新 key 后恢复,问题通常出在旧 key、旧项目或相关配额配置上。如果仍然失败,则需要继续检查 API 启用状态、请求方式、短周期配额和账号计费状态。
测试 key 只能用于定位问题。确认原因后应将其删除或轮换,不能把它当作长期绕过配额的方案。
仍无法恢复时
向 Google Maps Platform 支持提交问题时,应提供:
- Cloud project ID
- 受影响的 API 名称
- 请求发生的准确时间和时区
- 完整错误状态及脱敏后的
error_message - API key 的脱敏标识
- 配额页面中有效限制为
1的指标名称 - billing 绑定状态和相关截图
- 问题是否只发生在生产环境
- 典型失败请求的脱敏示例
不要提交完整 API key、签名密钥或其他可复用凭据。
最后需要核对整条请求链路,确保生产请求使用的 key、key 所属项目、项目启用的 Places API,以及该项目绑定的 billing 和有效配额彼此一致。只看到其中某一项显示 unlimited,不能证明实际请求拥有无限额度。
备注:内容仅供参考。
