拦截器(Interceptors)

解释了如何使用拦截器实现适用于许多 RPC 方法的通用行为。

概述

创建 gRPC 服务的核心是实现 RPC 方法。但是有些功能与执行的方法无关,应该适用于所有或大多数 RPC。拦截器非常适合这一任务。

何时使用拦截器

您可能已经熟悉拦截器的概念,可能习惯将它们称为 “过滤器” 或 “中间件”。拦截器非常适合实现与单个 RPC 方法无关的逻辑。它们还很容易在不同的客户端或服务器之间共享。拦截器是扩展 gRPC 的一个重要且常用的方式。您可能会发现,您需要的一些功能已经作为拦截器在更广泛的 gRPC 生态系统中可用。

一些常见的拦截器使用场景包括:

  • 元数据 处理

  • 日志记录

  • 故障注入

  • 缓存

  • 指标

  • 策略执行

  • 服务器端身份验证

  • 服务器端授权

虽然客户端身份验证可以通过拦截器完成,但 gRPC 提供了一个专门的 “调用凭证”(call credentials)API,它更适合此任务。有关客户端身份验证的详细信息,请参见 身份验证指南

如何使用拦截器

拦截器可以在构建 gRPC 通道或服务器时添加。然后,拦截器会为该通道或服务器上的每个 RPC 被调用。客户端和服务器端的拦截器 API 是不同的,因此拦截器可以是 “客户端拦截器” 或 “服务器端拦截器”。

拦截器本质上是按调用执行的;它们不适用于管理 TCP 连接、配置 TCP 端口或配置 TLS。虽然拦截器是大多数自定义化的正确工具,但并不能用于所有情况。

拦截器的顺序

当使用多个拦截器时,它们的顺序是重要的。您需要理解您的 gRPC 实现将如何执行这些拦截器。可以将拦截器想象成位于应用程序和网络之间的一条线。有些拦截器会“更接近网络”,并对发送的内容有更多控制,而其他拦截器则会“更接近应用程序”,能更好地了解应用程序的行为。

假设您有两个客户端拦截器:缓存拦截器和日志拦截器。它们的顺序应该是怎样的?您可能希望将日志拦截器放置在更接近网络的位置,这样可以更好地监控应用程序的通信并忽略缓存的 RPC:

image 2024 12 24 10 27 09 642

或者,您可能希望将它放置在更接近应用程序的位置,以便理解应用程序的行为并查看它加载了哪些信息:

image 2024 12 24 10 27 24 490

您只需通过更改拦截器的顺序就可以选择这两种选项。

语言支持

语言 示例

C++

C++ 示例

Go

Go 示例

Java

Java 示例

Python

Python 示例