gRPC从0到1系列【20】

文章目录

  • 七、gRPC拦截器
    • [7.1 拦截器概述](#7.1 拦截器概述)
      • [7.1.1 什么是gRPC拦截器?](#7.1.1 什么是gRPC拦截器?)
      • [7.1.2 拦截器的类型划分](#7.1.2 拦截器的类型划分)
      • [7.1.3 核心接口](#7.1.3 核心接口)
      • [7.1.4 调用链](#7.1.4 调用链)
      • [7.1.5 流程图](#7.1.5 流程图)
    • [7.2 工作原理与生命周期](#7.2 工作原理与生命周期)
      • [7.2.1 拦截器处理流程](#7.2.1 拦截器处理流程)
      • [7.2.2 拦截器的执行顺序](#7.2.2 拦截器的执行顺序)

七、gRPC拦截器

7.1 拦截器概述

7.1.1 什么是gRPC拦截器?

gRPC 拦截器是一种AOP (面向切面编程) 的实现,允许你在 RPC 调用的生命周期的特定节点(如调用前、调用后、出错时)注入自定义逻辑,而无需修改 RPC 方法本身的业务代码。

你可以把拦截器想象成 RPC 调用的 "安检员" 或 "门卫"

  • 在调用到达业务逻辑之前:检查调用者的身份(认证)、记录请求日志、修改或添加元数据。
  • 在业务逻辑执行之后:记录响应日志、收集性能指标(如耗时)、修改或添加响应的元数据。
  • 在发生异常时 :记录错误日志、将业务异常转换为标准的 gRPC Status 错误。

拦截器的核心价值在于解耦:将与业务无关的通用功能(如日志、监控、安全)从业务代码中分离出来,实现代码的模块化和复用。

7.1.2 拦截器的类型划分

gRPC 拦截器分为 客户端服务端 两大类,每类又根据 RPC 模式细分:

✅ 1. 服务器端拦截器【ServerInterceptor】

RPC 类型 拦截器方法签名(Java)
Unary(一元) UnaryServerInterceptor
Server Streaming ServerStreamingServerInterceptor
Client Streaming ClientStreamingServerInterceptor
Bidirectional Streaming BidiStreamingServerInterceptor

通用做法 :使用 ServerInterceptor 接口(底层自动适配所有类型)

✅ 2. 客户端拦截器【ClientInterceptor】

RPC 类型 拦截器方法签名(Java)
Unary UnaryClientInterceptor
Streaming(三种流) StreamingClientInterceptor

通用做法 :使用 ClientInterceptor 接口

7.1.3 核心接口

java 复制代码
// 服务端拦截器
public interface ServerInterceptor {
  <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
      ServerCall<ReqT, RespT> call,
      Metadata headers,
      ServerCallHandler<ReqT, RespT> next);
}

// 客户端拦截器
public interface ClientInterceptor {
  <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
      MethodDescriptor<ReqT, RespT> method,
      CallOptions callOptions,
      Channel next);
}

7.1.4 调用链

bash 复制代码
客户端: 
[App] → [Interceptor1] → [Interceptor2] → ... → [Network]

服务端:
[Network] → [Interceptor1] → [Interceptor2] → ... → [Business Logic]
  • next 参数:代表"下一个拦截器或最终处理者"
  • 必须调用 next.xxx(),否则调用链中断!

7.1.5 流程图

7.2 工作原理与生命周期

7.2.1 拦截器处理流程

拦截器的工作基于责任链模式 (Chain of Responsibility)。你可以为一个 gRPC 通道(Channel)或服务注册多个拦截器,它们会按特定顺序形成一个 "拦截器链"。

一元 RPC (Unary RPC) 的拦截流程 (以服务端为例):
Client InterceptorChain LoggingInterceptor AuthInterceptor BusinessLogic 1. Send RPC Request 2. Invoke interceptor 3. Check credentials in Metadata 4. Proceed to next interceptor 5. Log request details 6. Proceed to business logic 7. Execute business code 8. Return response 9. Log response details 10. Return response 11. Return response 12. Send RPC Response 4. Return error (UNAUTHENTICATED) 5. Send RPC Error alt [Valid] [Invalid] Client InterceptorChain LoggingInterceptor AuthInterceptor BusinessLogic

核心方法:

  • Context: 每个 RPC 调用都关联一个 Context对象,它像一个 "上下文" 或 "环境",可以在拦截器链和业务逻辑之间传递数据(如用户身份信息)。它是不可变的,但可以通过 withValue() 创建一个包含新值的子上下文。
  • next 在拦截器的实现中,ServerCallHandler (服务端) 或 ClientCall (客户端) 对象通常被命名为 next。调用 next.startCall()或 next.invoke()意味着将 RPC 调用传递给链中的下一个拦截器 。如果当前拦截器是最后一个,则 next 指向实际的业务逻辑实现。如果不调用 next,整个调用链将被中断。

7.2.2 拦截器的执行顺序

java 复制代码
package com.example.grpc.interceptor;

import io.grpc.*;

/**
 * gRPC 拦截器核心概念演示
 */
public class InterceptorConcepts {
    
    /**
     * 拦截器执行顺序示意图
     * 
     * 客户端拦截器执行顺序: 添加顺序 → 实际调用 → 响应顺序
     * 服务器拦截器执行顺序: 添加顺序 → 实际处理 → 响应顺序
     */
    
    // 客户端调用流程
    public static void demonstrateClientFlow() {
        System.out.println("=== 客户端拦截器执行顺序 ===");
        System.out.println("1. 请求拦截器 (正向顺序)");
        System.out.println("2. 实际RPC调用");
        System.out.println("3. 响应拦截器 (逆向顺序)");
    }
    
    // 服务器调用流程  
    public static void demonstrateServerFlow() {
        System.out.println("=== 服务器拦截器执行顺序 ===");
        System.out.println("1. 请求拦截器 (正向顺序)");
        System.out.println("2. 实际服务处理");
        System.out.println("3. 响应拦截器 (逆向顺序)");
    }
}
  • 客户端拦截器执行顺序: 添加顺序 → 实际调用 → 响应顺序
  • 服务器拦截器执行顺序: 添加顺序 → 实际处理 → 响应顺序
相关推荐
万邦科技Lafite4 小时前
如何对接API接口?需要用到哪些软件工具?
java·前端·python·api·开放api·电商开放平台
1710orange4 小时前
java设计模式:静态代理模式
java·设计模式·代理模式
我真的是大笨蛋5 小时前
开闭原则详解(OCP)
java·设计模式·性能优化·开闭原则·设计规范
编啊编程啊程5 小时前
gRPC从0到1系列【19】
java·spring boot·rpc·dubbo·nio
泥嚎泥嚎5 小时前
【Android】Android 的三种动画(帧动画、View 动画、属性动画)
java
不良人天码星5 小时前
使用Java连接redis以及开放redis端口的问题
java·开发语言·redis
马克学长5 小时前
SSM村务管理系统s2qnw(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
java·服务器·数据库
羊锦磊5 小时前
[ Spring 框架 ] 数据访问和事务管理
java·后端·spring
未来coding5 小时前
Spring Boot SSE 流式输出,智能体的实时响应
java·spring boot·后端