【gRPC】header和trailer两种元数据机制go案例

devtools/2025/1/13 3:16:52/

gRPC Header 和 Trailer

gRPC 提供了 HeaderTrailer 两种元数据机制,用于在客户端和服务端之间传递附加信息。

Header 和 Trailer 的区别

元数据类型发送时机常见用途
HeaderRPC 调用开始时,随响应发送包含认证信息、会话数据、请求相关的元信息(如客户端ID)。
TrailerRPC 调用结束时,随结束状态发送传递结束状态、处理统计数据(如耗时)、错误信息等。

服务端实现:带认证和性能监控

package mainimport ("context""log""time""google.golang.org/grpc""google.golang.org/grpc/metadata"pb "your_project_path/protos" // 替换为实际的proto包路径
)type MyService struct {pb.UnimplementedYourServiceServer // 嵌套未实现的服务
}func (s *MyService) MyMethod(ctx context.Context, req *pb.MyRequest) (*pb.MyResponse, error) {// 模拟身份验证if err := s.validateAuth(ctx); err != nil {return nil, err}// 设置 Header 元数据header := metadata.Pairs("request-id", req.GetRequestId(),"server-timestamp", time.Now().Format(time.RFC3339),)if err := grpc.SendHeader(ctx, header); err != nil {log.Printf("Failed to send header: %v", err)return nil, err}// 处理业务逻辑start := time.Now()response := &pb.MyResponse{Message: "Hello from the server!",}processTime := time.Since(start)// 设置 Trailer 元数据trailer := metadata.Pairs("status", "success","process-time", processTime.String(),)grpc.SetTrailer(ctx, trailer)return response, nil
}func (s *MyService) validateAuth(ctx context.Context) error {md, ok := metadata.FromIncomingContext(ctx)if !ok {return grpc.Errorf(codes.Unauthenticated, "missing metadata")}authTokens := md["authorization"]if len(authTokens) == 0 || authTokens[0] != "Bearer enterprise-token" {return grpc.Errorf(codes.Unauthenticated, "invalid token")}return nil
}

客户端实现:集成请求追踪和元数据解析

package mainimport ("context""fmt""log""time""google.golang.org/grpc""google.golang.org/grpc/metadata"pb "your_project_path/protos" // 替换为实际的proto包路径
)func main() {conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())if err != nil {log.Fatalf("Failed to connect: %v", err)}defer conn.Close()client := pb.NewYourServiceClient(conn)// 创建上下文并附加元数据ctx := metadata.AppendToOutgoingContext(context.Background(),"authorization", "Bearer enterprise-token","trace-id", "trace-12345",)// 用于接收服务端返回的 Header 和 Trailervar header, trailer metadata.MD// 发起请求resp, err := client.MyMethod(ctx, &pb.MyRequest{RequestId: "req-12345"}, grpc.Header(&header), grpc.Trailer(&trailer))if err != nil {log.Fatalf("RPC failed: %v", err)}// 打印响应fmt.Printf("Response: %s\n", resp.Message)// 打印 Header 和 Trailerfmt.Println("Header received:")for k, v := range header {fmt.Printf("  %s: %v\n", k, v)}fmt.Println("Trailer received:")for k, v := range trailer {fmt.Printf("  %s: %v\n", k, v)}
}

实用场景与注意事项

  • 场景

    • Header:验证身份、传递上下文信息,如 auth-tokentrace-id
    • Trailer:返回状态或统计信息,如 process-timestatus
  • 注意事项

    1. Header 在响应开始时发送,Trailer 在响应结束后发送。
    2. 键值均为字符串,推荐键使用小写,遵循 gRPC metadata 规范。
    3. 使用 trace-id 或类似机制,在分布式系统中实现请求追踪。

示例元数据结构

Header:

request-id: req-12345
server-timestamp: 2025-01-06T10:15:30Z

Trailer:

status: success
process-time: 45ms

http://www.ppmy.cn/devtools/150040.html

相关文章

体育实时数据是怎么获取的

体育实时数据的获取通常依赖于技术、数据提供商以及基础设施的综合应用。以下是主要的获取方式和技术手段: 1. 官方渠道数据接口 体育联赛与赛事方的API:一些官方机构(如FIFA、NBA、MLB等)提供实时数据接口,这些接口…

汽车物资拍卖系统架构与功能分析

2015工作至今,10年资深全栈工程师,CTO,擅长带团队、攻克各种技术难题、研发各类软件产品,我的代码态度:代码虐我千百遍,我待代码如初恋,我的工作态度:极致,责任&#xff…

Spring实现通过工具类统一输出日志(不改变日志类信息)

版权说明: 本文由CSDN博主keep丶原创,转载请保留此块内容在文首。 原文地址: https://blog.csdn.net/qq_38688267/article/details/145022997 背景 实现输出带动态标签的日志需求后,实际操作过程中,输出日志的代码为&a…

【线性代数】通俗理解特征向量与特征值

这一块在线性代数中属于重点且较难理解的内容,下面仅个人学习过程中的体会,错误之处欢迎指出,有更简洁易懂的理解方式也欢迎留言学习。 文章目录 概念计算几何直观理解意义PS.适用 概念 矩阵本身就是一个线性变换,对一个空间中的…

为AI聊天工具添加一个知识系统 开发环境准备

现在,我准备开始开发这个项目,需要搭建开发环境 并将前面的程序整理到项目文件中。请完成--我是一个新手 好的!我将帮助您从头开始搭建开发环境,并整理好之前的程序代码到项目文件中,以便您可以轻松启动这个项目。以下…

模式识别-Ch3-贝叶斯估计

贝叶斯估计 贝叶斯估计是概率密度估计中另一类主要的参数估计方法。其结果在很多情况下与最大似然法十分相似,但是,两种方法对问题的处理视角是不一样的。 贝叶斯估计最大似然估计将待估计的参数视为一个随机变量,其中的一个核心任务是根据…

【每日学点鸿蒙知识】关于热修复、图片预览、多个@State刷新性能问题等

1、是否推荐使用bm quickfix制造修复包? 官方文档文档中显示:快速修复补丁安装bm quickfix -a -f /data/app/有两个问题: hqf文件如何制作的文档没有找到。hqf 是不是新版本和旧版本的差分包咨询场景描述:app可以在运行过程中修…

Docker Compose 教程

Docker Compose 是一个 Docker 容器的依赖管理工具。 例如我们一个服务需要依赖到多个 Docker 容器,那么使用 Docker Compose 这个工具就能很方便的帮助我们管理。 Docker Compose 通过配置文件 .yml。 定义了所有容器的依赖关系。 然后我们只需把我们想要的 Docke…