状态与错误
Status、Metadata、deadline。
25 分钟
状态与错误
gRPC 用 Status(code + description)与 Metadata 传递错误;客户端通过 StatusRuntimeException 处理。与 REST 的 HTTP 状态码 概念对应、映射非 1:1。
学习目标
- 使用标准
Status.Code(NOT_FOUND、INVALID_ARGUMENT等) - 在 Metadata 中传递 trace-id、业务错误码
- 配置 deadline 避免级联阻塞
核心内容
Status 对照 REST
| gRPC Code | 近似 REST | 本站示例 |
|---|---|---|
OK | 200 | 正常返回 track |
NOT_FOUND | 404 | slug 不存在 |
INVALID_ARGUMENT | 400 | 空 slug |
UNAUTHENTICATED | 401 | 缺 mTLS/ token |
DEADLINE_EXCEEDED | 504 | 下游超时 |
UNAVAILABLE | 503 | 服务未启动 |
REST TrackController 返回 ResponseEntity.notFound();gRPC lab 用 Status.NOT_FOUND——同一业务,不同传输语义。
服务端抛错
if (req.getSlug().isBlank()) {
resp.onError(Status.INVALID_ARGUMENT
.withDescription("slug required")
.asRuntimeException());
return;
}
resp.onError(Status.NOT_FOUND
.withDescription("track: " + req.getSlug())
.asRuntimeException());
Metadata 与拦截器
Metadata.Key<String> TRACE =
Metadata.Key.of("x-trace-id", Metadata.ASCII_STRING_MARSHALLER);
Metadata trailers = new Metadata();
trailers.put(TRACE, MDC.get("traceId"));
resp.onError(Status.INTERNAL.asRuntimeException(trailers));
Spring 可用 ServerInterceptor 统一注入 trace,对齐 spring-boot-essentials 日志 MDC。微服务链路透传见 spring-cloud-essentials Sleuth/Micrometer。
Deadline
// 客户端
stub.withDeadlineAfter(3, TimeUnit.SECONDS).getTrack(req);
// 服务端检查
if (Context.current().isCancelled()) { /* 尽早退出 */ }