您的位置:首页 > 文旅 > 美景 > 河南郑州消费情况_个人简历模板word可编辑_搭建网站多少钱_网站开发流程

河南郑州消费情况_个人简历模板word可编辑_搭建网站多少钱_网站开发流程

2025/1/8 20:32:13 来源:https://blog.csdn.net/m0_74282926/article/details/144987828  浏览:    关键词:河南郑州消费情况_个人简历模板word可编辑_搭建网站多少钱_网站开发流程
河南郑州消费情况_个人简历模板word可编辑_搭建网站多少钱_网站开发流程

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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com