背景与价值GraphQL易被构造高成本查询。统一复杂度与深度限制并与速率策略协同,可在入口阻断滥用。统一规范深度上限:例如最大深度5。复杂度上限:为字段赋予成本权重并聚合,超限拒绝。速率协同:成本高的请求降低速率阈值。核心实现AST简化与复杂度计算(示意)type Node = { name: string; children?: Node[] } const weight: Record<string, number> = { user: 1, users: 3, posts: 2, comments: 3, profile: 1 } function depth(node: Node): number { if (!node.children || node.children.length === 0) return 1; return 1 + Math.max(...node.children.map(depth)) } function cost(node: Node): number { const w = weight[node.name] || 1; const child = (node.children || []).reduce((s, n) => s + cost(n), 0); return w + child } function withinLimits(root: Node, maxDepth: number, maxCost: number): boolean { return depth(root) <= maxDepth && cost(root) <= maxCost } 速率协同门禁function bucket(costVal: number): number { if (costVal <= 10) return 10; if (costVal <= 30) return 5; return 2 } class Rate { tokens = new Map<string, { left: number; resetAt: number }>() now(): number { return Date.now() } refill(k: string, capacity: number, windowMs: number) { const r = this.tokens.get(k); const n = this.now(); if (!r || n >= r.resetAt) this.tokens.set(k, { left: capacity, resetAt: n + windowMs }) } take(k: string): boolean { const r = this.tokens.get(k); if (!r) return false; if (r.left <= 0) return false; r.left--; return true } } function gateRate(rate: Rate, id: string, costVal: number): boolean { const cap = bucket(costVal); rate.refill(id, cap, 60000); return rate.take(id) } 落地建议为核心字段设置成本权重并统一深度上限,按业务场景调整阈值。将复杂度结果与速率限制协同,动态限流高成本查询以防资源耗尽。审计拒绝事件与高成本请求路径,持续优化Schema与字段权重。验证清单查询深度与复杂度是否在上限内,速率是否按成本动态调整。

发表评论 取消回复