节点限制
若要通过架构验证,所有 GraphQL API 调用都必须满足以下标准:
计算调用中的节点
下面两个示例显示如何计算调用中的节点总数。
-
简单查询:
query { viewer { repositories(first: 50) { edges { repository:node { name issues(first: 10) { totalCount edges { node { title bodyHTML } } } } } } } }
计算:
50 = 50 repositories + 50 x 10 = 500 repository issues = 550 total nodes
-
复杂查询:
query { viewer { repositories(first: 50) { edges { repository:node { name pullRequests(first: 20) { edges { pullRequest:node { title comments(first: 10) { edges { comment:node { bodyHTML } } } } } } issues(first: 20) { totalCount edges { issue:node { title bodyHTML comments(first: 10) { edges { comment:node { bodyHTML } } } } } } } } } followers(first: 10) { edges { follower:node { login } } } } }
计算:
50 = 50 repositories + 50 x 20 = 1,000 pullRequests + 50 x 20 x 10 = 10,000 pullRequest comments + 50 x 20 = 1,000 issues + 50 x 20 x 10 = 10,000 issue comments + 10 = 10 followers = 22,060 total nodes
主要速率限制
GraphQL API 为每个查询分配了点数,并且限制了可在特定时间内使用的点数。 此限制有助于防止滥用和拒绝服务攻击,并确保 API 仍可供所有用户使用。
REST API 还具有单独的主要速率限制。 有关详细信息,请参阅“REST API 的速率限制”。
通常,可以根据身份验证方法计算 GraphQL API 的主要速率限制:
- 对于用户__:每用户每小时 5,000 点。 这包括使用 personal access token 发出的请求,以及由 GitHub App 或 OAuth app 代表授权应用的用户发出的请求。 对于由 GitHub Enterprise Cloud 组织所有的 GitHub App 代表用户发出的请求,速率限制更高,为每小时 10,000 点。 同样,如果你是 GitHub Enterprise Cloud 组织的成员,则对于由 GitHub Enterprise Cloud 组织拥有或批准的 OAuth app 代表你发出的请求,速率限制也更高,为每小时 10,000 点。
- 对于不在 GitHub Enterprise Cloud 组织中的 GitHub App 安装__:每个安装每小时 5,000 点。 如果安装的仓库数量超过 20 个,则每仓库每小时另外 50 点。 如果安装仓库的组织拥有超过 20 位用户,则每用户每小时另加 50 点。 速率限制上调的上限为每小时 12,500 点。 用户访问令牌(而不是安装访问令牌)的速率限制由用户的主要速率限制决定。
- 对于不在 GitHub Enterprise Cloud 组织中的 GitHub App 安装__:每个安装每小时 10,000 点。 用户访问令牌(而不是安装访问令牌)的速率限制由用户的主要速率限制决定。
- 对于 OAuth apps__:每小时 5,000 点,如果应用由 GitHub Enterprise Cloud 组织拥有,则为每小时 10,000 点。 这仅适用于应用使用其客户端 ID 和客户端密码来请求公开数据时。 对于由 OAuth app 生成的 OAuth 访问令牌,主要速率限制由用户的主要速率限制决定。
- 对于 GitHub Actions 工作流 中的
GITHUB_TOKEN
__:每仓库每小时 1,000 点。 对于 GitHub.com 上的企业帐户所属资源的请求,限制为每仓库每小时 15,000 点。
可以按以下章节所述来检查查询的点数值,或计算预期的点数值。 计算点数的公式和速率限制可能随时更改。
检查主要速率限制的状态
可以使用随每个响应一起发送的标头来确定主要速率限制的当前状态。
标头名称 | 说明 |
---|---|
x-ratelimit-limit | 每小时可以使用的最大点数 |
x-ratelimit-remaining | 当前速率限制窗口中剩余的点数 |
x-ratelimit-used | 当前速率限制窗口中已经使用的点数 |
x-ratelimit-reset | 当前速率限制窗口重置的时间,单位为 UTC 纪元秒 |
x-ratelimit-resource | 请求计数的速率限制资源。 对于 GraphQL 请求,这将始终为 graphql 。 |
还还可以通过查询 rateLimit
对象来检查速率限制。 情况允许时应使用速率限制响应头,而不是使用查询 API 来检查速率限制。
query {
viewer {
login
}
rateLimit {
limit
remaining
used
resetAt
}
}
字段 | 说明 |
---|---|
limit | 每小时可以使用的最大点数 |
remaining | 当前速率限制窗口中剩余的点数 |
used | 当前速率限制窗口中已经使用的点数 |
resetAt | 当前速率限制窗口重置的时间,单位为 UTC 纪元秒 |
返回查询的点数值
可以通过查询 cost
对象上的 rateLimit
字段来返回查询的点数值:
query {
viewer {
login
}
rateLimit {
cost
}
}
预测查询的点数值
在进行查询之前,还可以大致计算查询的点数值。
- 将完成调用中每个独有连接所需的请求数加起来。 假设每个请求都将达到
first
或last
参数限制。 - 将计算所得的数字除以 100****,然后将结果四舍五入为最接近的整数,即可获取最终加总点数值。 这一步可使大数字规范化。
Note
对 GraphQL API 的调用的最小点数值为 1****。
下面是一个查询和分数计算示例:
query {
viewer {
login
repositories(first: 100) {
edges {
node {
id
issues(first: 50) {
edges {
node {
id
labels(first: 60) {
edges {
node {
id
name
}
}
}
}
}
}
}
}
}
}
}
此查询需要 5,101 个请求才能完成:
- 虽然我们要返回 100 个存储库,但 API 必须连接到查看器的帐户一次才能获取存储库列表。 因此,存储库的请求 = 1
- 虽然我们要返回 50 个问题,但 API 必须与 100 个存储库的每个库相连接,才能获取问题列表。 因此,问题请求 = 100
- 虽然我们要返回 60 个标签,但 API 必须与 5,000 个潜在总问题中的每个问题相连接,才能获取标签列表。 因此,标签请求 = 5,000
- 总计 = 5,101
除以100,然后四舍五入就得到了查询的最终分数:51
二级费率限制
除了主要速率限制以外,GitHub 还强制执行次要速率限制以阻止滥用,让 API 可供所有用户所使用。
以下情况下可能会遇到次要速率限制:
- 发出的并发请求过多。 并发请求数量不能超过 100 个。 REST API 和 GraphQL API 都应用此限制。
- 每分钟向单个终结点发出的请求数过多。 REST API 终结点每分钟允许发出的请求数不超过 900 点,GraphQL API 终结点每分钟允许发出的请求数不过超 2,000 点。 有关点的详细信息,请参阅“计算次要速率限制的点数”。
- 每分钟发出的请求数过多。 实时每 60 秒允许的 CPU 时间不超过 90 秒。 此 CPU 时间的 60 秒不能超过 GraphQL API。 可以通过衡量 API 请求的总响应时间来大致估算出 CPU 时间。
- 发出过多的请求,它们在短时间内会消耗过多的计算资源。
- 短时间内在 GitHub 上创建的内容过多。 一般情况下,每分钟不超过 80 个内容生成请求,允许每小时不超过 500 个内容生成请求。 某些终结点的内容创建限制较低。 内容创建限制包括对 GitHub Web 界面以及 REST API 和 GraphQL API 执行的操作。
上述次要速率限制可能随时更改,恕不另行通知。 可能还会因未公开的原因而遇到次要速率限制。
计算次要速率限制的点数
某些次要速率限制由请求的点值确定。 对于 GraphQL 请求,这些点值与主要速率限制的点值分开来进行计算。
请求 | 点 |
---|---|
不具有突变的 GraphQL 请求 | 1 |
具有突变的 GraphQL 请求 | 5 |
大多数 REST API GET 、HEAD 和 OPTIONS 请求 | 1 |
大多数 REST API POST 、PATCH 、PUT 或 DELETE 请求 | 5 |
某些 REST API 终结点具有不公开共享的不同点成本。
超出速率限制
如果超出主要速率限制,响应状态仍将是 200
,但会收到错误消息,并且 x-ratelimit-remaining
标头的值将为 0
。 应在 x-ratelimit-reset
标头所指定的时间之后,再尝试发出请求。
如果超出次要速率限制,则响应状态将为 200
或 403
,并显示一条错误消息,表明超出了了次要速率限制。 如果有 retry-after
响应头,则应先等待数秒,然后再尝试请求。 如果 x-ratelimit-remaining
标头为 0
,应在 x-ratelimit-reset
标头所指定的时间(以 UTC 新纪元时间秒为单位)之后,再尝试发出请求。 否则,请在重试之前等待至少一分钟。 如果请求由于次要速率限制而继续失败,请等待呈指数级增加的重试间隔秒数,当达到特定的重试次数之后,将会抛出错误。
如果在受到速率限制的情况下继续发出请求,可能会导致禁止集成。
保持在速率限制范围内
要避免超出速率限制,应在可变请求之间至少暂停 1 秒,并且不要发出并发请求。
此外还应订阅 Webhook 事件,而不是通过轮询 API 来获取数据。 有关详细信息,请参阅“Webhook 文档”。
还可以流式传输审核日志来查看 API 请求。 这有助于排查超出速率限制的集成问题。 有关详细信息,请参阅“流式处理企业审核日志”。