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. 响应拦截器 (逆向顺序)");
    }
}
  • 客户端拦截器执行顺序: 添加顺序 → 实际调用 → 响应顺序
  • 服务器拦截器执行顺序: 添加顺序 → 实际处理 → 响应顺序
相关推荐
倚肆4 小时前
HttpServletResponse 与 ResponseEntity 详解
java·后端·spring
悟能不能悟4 小时前
java List怎么转换为Vector
java·windows·list
yaoxin5211234 小时前
241. Java 集合 - 使用 Collections 工厂类处理集合
java·windows
依_旧4 小时前
【玩转全栈】----Django基本配置和介绍
java·后端
white-persist4 小时前
差异功能定位解析:C语言与C++(区别在哪里?)
java·c语言·开发语言·网络·c++·安全·信息可视化
kokunka4 小时前
C#类修饰符功能与范围详解
java·开发语言·c#
冰芒芒4 小时前
Kafka - 4 Kafka的副本同步机制
分布式·kafka
大大水瓶4 小时前
Nginx学习
学习·nginx·dubbo
仟濹4 小时前
【Java 基础】3 面向对象 - this
java·开发语言·python
百***35515 小时前
什么是Spring Boot 应用开发?
java·spring boot·后端