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

调用Google Chat API批量发消息返回429错误的原因及解决方法

Google Chat API 429错误问题解答

接口瞬时请求阈值说明

控制台标注的每分钟6000次写请求是分钟级维度的总配额,除此之外API还有未展示在配额页面的短周期突发限流规则:

  • 服务账号维度全局写请求瞬时阈值为 10 QPS(每秒10次请求)
  • 单个聊天空间维度的写请求瞬时阈值为 5 QPS(每秒5次请求)
    以上短周期限流的统计周期为1秒/10秒级,用量不会同步到控制台分钟级配额的统计面板中。

本次报错触发原因

  • 核心原因是请求密度超过短周期限流阈值:现有代码采用无间隔循环串行调用接口,批量发消息时短时间内的请求峰值超过了单空间/全局的瞬时QPS上限,触发网关层面的突发流量拦截,和分钟级总配额无关,因此会出现配额页显示用量远低于上限但返回429的情况。
  • 代码未配置限流适配逻辑:现有逻辑遇到429错误直接返回,没有做请求间隔控制、也没有针对限流的重试机制,请求连续打向接口时很容易触发拦截。
  • 如果批量发送的内容重复度极高,还会额外触发API的反垃圾限流规则,同样会返回资源耗尽的429错误。

可行解决方法

  • 增加请求间隔削峰:批量发送消息时在循环中加入固定等待间隔,单空间发信控制在每秒3-4次的频率,全局总请求控制在每秒8次以内,预留足够阈值冗余,不要卡着限流值发送。
  • 实现指数退避重试:捕获429错误时优先读取响应头的Retry-After字段,按标注时长等待后重试;如果没有该字段则采用指数退避策略,首次等待1秒、第二次等待2秒、第三次等待4秒,最多重试3次即可覆盖绝大多数限流场景。
  • 合并消息减少请求量:同一场景的多条通知类消息可以合并为单条富文本消息发送,从根源降低请求总量。
  • 调整发信内容:避免批量发送完全重复的模板化内容,减少触发反垃圾拦截的概率。

优化后的调用代码示例

import time
from random import random
from oauth2client.service_account import ServiceAccountCredentials
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

def get_client(service):
    scopes_chat = 'https://www.googleapis.com/auth/chat.bot'
    if service == "hangouts":
        credentials = ServiceAccountCredentials.from_json_keyfile_name(s_account, scopes_chat)
        return build('chat', 'v1', http=credentials.authorize(Http()), cache_discovery=False)

def send_alert_chat_notification(messages_with_product):
    hchat = get_client("hangouts")
    messages = messages_with_product[product]
    for message in messages:
        max_retry = 3
        retry_count = 0
        while retry_count < max_retry:
            try:
                hchat.spaces().messages().create(
                    parent=space_name,
                    body=message).execute()
                # 发完每条加0.3秒间隔,叠加随机抖动避免固定频率撞限流
                time.sleep(0.3 + random()*0.1)
                break
            except HttpError as e:
                if e.resp.status == 429:
                    retry_count += 1
                    # 优先读取Retry-After头,没有则走指数退避
                    retry_after = e.resp.get('Retry-After', 2**retry_count)
                    time.sleep(int(retry_after))
                    continue
                else:
                    logger.error("HTTP Error: Status: {}, Error: {}".format(str(e.resp.status), str(e)))
                    raise e
        if retry_count == max_retry:
            logger.error("Message send failed after max retries: {}".format(str(message)))

实际报错返回参考:
ERROR - HTTP Error: Status: 429, Error: <HttpError 429 when requesting https://chat.googleapis.com/v1/spaces/***/messages?alt=json returned "Resource has been exhausted (e.g. check quota).". Details: "Resource has been exhausted (e.g. check quota).">

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 04:42:10