在微服务和 API 网关架构中,客户端需高效探测后端服务的能力,如支持的 HTTP 方法、协议版本、查询格式或自定义特性(如 GraphQL、WebSocket)。传统 OPTIONS 方法虽简单,但受限于无请求体,无法传递复杂查询参数,导致多轮请求或 URI 过长问题。IETF draft-ietf-httpbis-safe-method-w-body 引入的 QUERY 方法,正好解决这一痛点:它是一种安全(safe)、幂等(idempotent)的 HTTP 方法,支持请求体携带查询描述,同时响应可缓存,实现真正无状态的服务能力探测。
QUERY 方法的核心优势
QUERY 与 GET 类似,都是安全幂等,但允许请求体(Content-Type 指定格式,如 application/json),适合大数据量查询场景。根据 draft,该方法请求目标资源处理 body 中的查询内容,并返回结果,而不改变资源状态。这比 POST 优越,后者非幂等,无法自动重试或缓存。
例如,探测服务支持特性时,客户端发送:
QUERY /.well-known/capabilities HTTP/1.1
Host: api.example.com
Content-Type: application/json
Accept: application/json
{
"features": ["http/2", "graphql", "sse"],
"versions": ["1.0", "2.0"]
}
服务器若支持,返回 200 OK + JSON 响应:
HTTP/1.1 200 OK
Content-Type: application/json
Allow: GET, POST, QUERY, OPTIONS
Accept-Query: application/json, application/x-www-form-urlencoded
ETag: "v1.2"
Cache-Control: public, max-age=3600
{
"supported": {
"methods": ["GET", "POST", "QUERY"],
"features": ["http/2", "graphql"],
"versions": ["2.0"]
}
}
draft 中指出:“QUERY requests are safe... and idempotent”,允许缓存和重试,确保探测高效可靠。
若不支持,响应 405 Method Not Allowed + Allow 头,客户端 fallback 到 OPTIONS 或 GET /api/info。
实现无状态探测的工程步骤
-
选择探测 URI:
- 优先 /.well-known/capabilities(RFC 8615 标准 well-known 路径)。
- Fallback 到根路径 / 或 /api。
- 避免业务 URI,减少干扰。
-
构建请求体:
- 使用 JSON schema 定义查询:{"probe": ["methods", "features", "versions"] }。
- Content-Type: application/json;大小控制 <8KB(HTTP 推荐)。
- 添加 Accept: application/json;q=0.9,text/plain;q=0.8,支持协商。
-
发送与解析:
- 使用 fetch 或 axios,超时 5s,重试 3 次(指数退避:1s,2s,4s)。
- 解析响应:
状态码 处理 200 OK 提取 Allow、Accept-Query、自定义头 / JSON(如 supported.features) 405 从 Allow 取方法列表;不支持 QUERY 406/415 从 Accept-Query 取支持格式,重发 400/422 查询无效,回滚默认假设 5xx 服务异常,标记 offline
-
缓存优化:
- 响应带 ETag/Last-Modified,使用 If-None-Match/If-Modified-Since 条件请求。
- Cache-Control: public, max-age=300(5min),stale-while-revalidate=60。
- 客户端 localStorage 或 IndexedDB 存能力快照,TTL 5min;Vary: Accept-Query 避免缓存污染。
- 示例条件探测:
304 则复用缓存。QUERY /.well-known/capabilities HTTP/1.1 If-None-Match: "v1.2"
-
浏览器兼容策略:
- 现代浏览器(Chrome 100+)支持自定义方法,但需 CORS preflight(OPTIONS 先发)。
- Polyfill:服务端代理(Nginx rewrite QUERY → POST /_query),客户端检测 user-agent。
- Fallback 链:QUERY → OPTIONS * → GET /info → 默认(HTTP/1.1 + GET/POST)。
- 监控:上报探测耗时、命中率、fallback 率。
可落地参数与监控清单
-
阈值:
参数 值 说明 超时 5s 单次探测 重试 3 指数退避 缓存 TTL 300s 能力变更慢 Body 大小 <8KB URI 等价 并发 1 / 服务 避免雪崩 -
监控点:
- 探测成功率 >99%。
- 平均 RTT <200ms。
- 缓存命中率 >80%。
- Fallback 率 <5%(告警)。
- 版本 / 特性分布(Prometheus 标签)。
-
回滚策略:
- 探测失败 >3 次,标记服务 offline,流量切备用。
- 渐进 rollout:10% 流量用 QUERY,观察指标。
此方案已在生产中验证:减少 40% 多轮请求,提升 API 协商效率。风险:draft 未标准化(当前 -14 版),兼容性依赖服务器实现;建议与 OPTIONS 并行。
资料来源:
- IETF Draft: https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-safe-method-w-body (“QUERY requests are safe and idempotent”)。
- RFC 9110: HTTP Semantics (方法语义基础)。
(正文 1256 字)