【GO开发工程师】grpc进阶#golang

【GO开发工程师】grpc进阶#golang

在这里插入图片描述

推荐个人主页:席万里的个人空间

文章目录

  • 【GO开发工程师】grpc进阶#golang
    • 1、protobuf
    • 2、grpc
      • 2.1、gRPC 的 Metadata机制
      • 2.2、grpc拦截器

1、protobuf

syntax = "proto3"; // 指定使用的 protobuf 版本为 proto3
import "google/protobuf/timestamp.proto"; // 导入 Google 提供的时间戳类型定义
option go_package = ".;proto_bak"; // 生成的 Go 语言代码的包名设定为当前目录下的 proto_bakservice Greeter { // 定义一个名为 Greeter 的服务rpc SayHello (HelloRequest) returns (HelloReply); // 在 Greeter 服务中定义一个远程过程调用 SayHello,接收 HelloRequest 参数,返回 HelloReply 结果
}enum Gender { // 定义一个枚举类型 GenderMALE = 0; // 枚举值 MALE,值为 0FEMALE = 1; // 枚举值 FEMALE,值为 1
}message HelloRequest { // 定义消息类型 HelloRequeststring name = 1; // 姓名字段,用于存储姓名信息,字段标签为 1string url = 2; // URL 字段,用于存储 URL 信息,字段标签为 2Gender g = 3; // Gender 类型的字段,用于存储性别信息,字段标签为 3map<string, string> mp = 4; // 字符串键值对映射字段,用于存储键值对信息,字段标签为 4google.protobuf.Timestamp addTime = 5; // 时间戳字段,用于存储添加时间信息,字段标签为 5,使用了导入的时间戳类型定义
}message HelloReply { // 定义消息类型 HelloReplystring message = 1; // 消息字段,用于存储消息内容,字段标签为 1
}

2、grpc

2.1、gRPC 的 Metadata机制

gRPC 的 Metadata 机制是一种用于在 gRPC 请求和响应中传递元数据的机制。元数据是键值对的集合,可以包含请求的附加信息,比如身份验证凭据、请求标识符、客户端信息等。

在 gRPC 中,元数据可以分为两类:

  1. 请求元数据(Request Metadata):这些是客户端在发起 gRPC 请求时发送的元数据。它们可以用于传递关于请求的附加信息,比如身份验证凭据、请求标识符、客户端信息等。

  2. 响应元数据(Response Metadata):这些是服务端在响应 gRPC 请求时发送的元数据。它们可以用于传递关于响应的附加信息,比如服务端处理结果、附加的状态信息等。

元数据以键值对的形式存在,键是字符串,值可以是任意的序列化数据。在 gRPC 中,元数据通常使用 HTTP/2 格式编码,并在 HTTP/2 标头中传输。

Metadata 机制的使用使得 gRPC 具有灵活的扩展性和自定义能力。开发者可以根据自己的需求,在请求和响应中传递任意类型的元数据,以实现各种功能,比如身份验证、流量控制、跟踪、日志记录等。

2.2、grpc拦截器

我想在每一个 RPC 方法的前面或后面做某些操作,我想针对某个业务模块的 RPC 方法进行统一的特殊处理,我想对 RPC 方法进行鉴权校验,我想对 RPC 方法进行上下文的超时控制,我想对每个 RPC 方法的请求都做日志记录,怎么做呢?

gRPC 的拦截器(Interceptors)是一种强大的功能,它允许在 gRPC 请求处理过程中注入自定义逻辑,类似于中间件。拦截器可以用于实现各种功能,如身份验证、日志记录、性能监控、流量控制等。在 gRPC 中,拦截器是通过使用 gRPC 的拦截器接口来实现的。

以下是一些常见的 gRPC 拦截器:

  1. 认证拦截器(Authentication Interceptor):用于对 gRPC 请求进行身份验证,以确保请求的安全性和合法性。

  2. 授权拦截器(Authorization Interceptor):用于在请求处理之前验证客户端是否具有执行请求操作的权限。

  3. 日志记录拦截器(Logging Interceptor):用于记录请求和响应的日志,以便进行故障排查、审计和性能分析。

  4. 性能监控拦截器(Performance Monitoring Interceptor):用于监控 gRPC 服务的性能指标,如请求处理时间、请求速率等。

  5. 流量控制拦截器(Traffic Control Interceptor):用于限制客户端请求的速率或配额,以确保服务端不会被过多的请求压力影响。

  6. 异常处理拦截器(Exception Handling Interceptor):用于捕获并处理 gRPC 服务中的异常情况,以提供更好的错误处理和用户体验。

有关go-grpc-middleware的使用:go-grpc-middleware下载地址

MD和拦截器案例

client.go

package mainimport ("OldPackageTest/grpc_test/proto" // 导入 protobuf 自动生成的代码包"context"                        // 导入 context 包"fmt"                            // 导入 fmt 包"google.golang.org/grpc"         // 导入 gRPC 包
)// customCredential 是一个自定义的 gRPC 凭据类型
type customCredential struct{}// GetRequestMetadata 实现了凭据接口中的 GetRequestMetadata 方法,
// 用于返回请求所需的元数据。
func (c customCredential) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {// 返回一个包含应用程序 ID 和密钥的元数据return map[string]string{"appid":  "101010","appkey": "i am key",}, nil
}// RequireTransportSecurity 实现了凭据接口中的 RequireTransportSecurity 方法,
// 返回该凭据是否需要传输安全性。
func (c customCredential) RequireTransportSecurity() bool {return false // 此示例中不需要传输安全性
}func main() {// 创建 gRPC 客户端连接选项数组var opts []grpc.DialOption// 添加使用不安全连接的 Dial 选项opts = append(opts, grpc.WithInsecure())// 添加使用自定义凭据的 Dial 选项opts = append(opts, grpc.WithPerRPCCredentials(customCredential{}))// 连接到 gRPC 服务器conn, err := grpc.Dial("127.0.0.1:50051", opts...)if err != nil {panic(err)}defer conn.Close() // 延迟关闭连接// 创建一个 GreeterClient 实例c := proto.NewGreeterClient(conn)// 向服务器发送 SayHello 请求,并传递 HelloRequest 参数r, err := c.SayHello(context.Background(), &proto.HelloRequest{Name: "bobby"})if err != nil {panic(err)}fmt.Println(r.Message) // 打印服务器返回的消息
}

helloworld.proto

syntax = "proto3";
option go_package = ".;proto";
service Greeter {rpc SayHello (HelloRequest) returns (HelloReply);
}
//将 sessionid放入 放入cookie中 http协议
//这个就好比文档,表单验证
message HelloRequest {string name = 1;
}message HelloReply {string message = 1;
}
//go语言中是生成一个文件, 也就只有python会生成两个文件

使用protoc生成go文件:

protoc --go_out=./ *.proto

server.go

package mainimport ("context""fmt""google.golang.org/grpc/codes" // 导入 gRPC 错误码包"google.golang.org/grpc/metadata" // 导入 gRPC 元数据包"google.golang.org/grpc/status" // 导入 gRPC 状态包"net" // 导入网络包"google.golang.org/grpc" // 导入 gRPC 包"OldPackageTest/grpc_test/proto" // 导入 protobuf 自动生成的代码包
)// Server 定义 gRPC 服务端结构体
type Server struct{}// SayHello 实现了 Greeter 服务中的 SayHello 方法
func (s *Server) SayHello(ctx context.Context, request *proto.HelloRequest) (*proto.HelloReply,error) {// 根据请求参数构造响应消息return &proto.HelloReply{Message: "hello " + request.Name,}, nil
}func main() {// 定义拦截器函数interceptor := func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {fmt.Println("接收到了一个新的请求") // 打印日志,表示接收到新的请求md, ok := metadata.FromIncomingContext(ctx) // 从上下文中获取请求的元数据fmt.Println(md)if !ok {// 如果无法获取元数据,则返回未认证错误return resp, status.Error(codes.Unauthenticated, "无token认证信息")}var (appid  string // 定义应用程序 IDappkey string // 定义应用程序密钥)// 从元数据中提取应用程序 ID 和密钥if va1, ok := md["appid"]; ok {appid = va1[0]}if va1, ok := md["appkey"]; ok {appkey = va1[0]}// 检查应用程序 ID 和密钥是否有效,若无效则返回未认证错误if appid != "101010" || appkey != "i am key" {return resp, status.Error(codes.Unauthenticated, "无token认证信息")}// 调用 gRPC 处理函数处理请求res, err := handler(ctx, req)fmt.Println("请求已经完成") // 打印日志,表示请求处理完成return res, err}// 创建 gRPC 服务器,并设置拦截器opt := grpc.UnaryInterceptor(interceptor)g := grpc.NewServer(opt)// 在 gRPC 服务器上注册 Greeter 服务proto.RegisterGreeterServer(g, &Server{})// 监听指定地址和端口lis, err := net.Listen("tcp", "0.0.0.0:50051")if err != nil {panic("failed to listen:" + err.Error())}// 启动 gRPC 服务器err = g.Serve(lis)if err != nil {panic("failed to start grpc:" + err.Error())}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/496594.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

牛客周赛 Round 34(A,B,C,D,E,F,G)

把这场忘了。。官方也迟迟不发题解 比赛链接 出题人题解 A 小红的字符串生成 思路&#xff1a; 枚举四种字符串打印出来即可&#xff0c;为了防止重复可以用set先去一下重。 code&#xff1a; #include <iostream> #include <cstdio> #include <cstring&g…

【服务发现--ingress】

1、ingress介绍 Ingress 提供从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源所定义的规则来控制。 Ingress 是对集群中服务的外部访问进行管理的 API 对象&#xff0c;典型的访问方式是 HTTP。 Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟…

【飞桨EasyDL】飞桨EasyDL发布的模型转换onnx(附工程代码)

一个愿意伫立在巨人肩膀上的农民...... 一、paddle转onnx转rknn环境搭建 paddle转onnx和onnx转rknn两个环境可以分开搭建&#xff0c;也可以搭建在一起。这里选择分开搭建&#xff0c;先搭建paddle转onnx。 1.1、创建环境 选择python3.8.13包进行创建环境 conda create --nam…

基于 LVGL 使用 SquareLine Studio 快速设计 UI 界面

目录 简介注册与软件获取工程配置设计 UI导出源码板级验证更多内容 简介 SquareLine Studio 是一款专业的 UI 设计软件&#xff0c;它与 LVGL&#xff08;Light and Versatile Graphics Library&#xff0c;轻量级通用图形库&#xff09;紧密集成。LVGL 是一个轻量化的、开源的…

Android和Linux的开发差异

最近开始投入Android的怀抱。说来惭愧&#xff0c;08年就听说这东西&#xff0c;当时也有同事投入去看&#xff0c;因为恶心Java&#xff0c;始终对这玩意无感&#xff0c;没想到现在不会这个嵌入式都快要没法搞了。为了不中年失业&#xff0c;所以只能回过头又来学。 首先还是…

瑞吉外卖项目详细分析笔记及所有功能补充代码

目录 项目刨析简介技术栈项目介绍项目源码 一.架构搭建1.初始化项目结构2.数据库表结构设计3.项目基本配置信息添加公共字段的自动填充全局异常处理类返回结果封装的实体类 二.管理端业务开发1.员工管理相关业务1.1员工登录1.2员工退出1.3过滤器拦截1.4员工信息修改1.5员工信息…

Java基础八股

基础概念与常识 Java 语言有哪些特点? 简单易学&#xff1b;面向对象&#xff08;封装&#xff0c;继承&#xff0c;多态&#xff09;&#xff1b;平台无关性&#xff08; Java 虚拟机实现平台无关性&#xff09;&#xff1b;支持多线程&#xff08; C 语言没有内置的多线程…

Python入门到精通(九)——Python数据可视化

Python数据可视化 一、JSON数据格式 1、定义 2、python数据和JSON数据转换 二、pyecharts 三、折线图 四、地图 五、动态柱状图 一、JSON数据格式 1、定义 JSON是一种轻量级的数据交互格式。可以按照JSON指定的格式去组织和封装数据JSON本质上是一个带有特定格式的字符…

Python学习系列 -初探标准库之logging库

系列文章目录 第一章 初始 Python 第二章 认识 Python 变量、类型、运算符 第三章 认识 条件分支、循环结构 第四章 认识 Python的五种数据结构 第五章 认识 Python 函数、模块 第六章 认识面向对象三大特性 第七章 初探标准库之os库 第八章 初探标准库之pathlib库 第九章 初探…

卷积神经网络介绍

卷积神经网络(Convolutional Neural Networks&#xff0c;CNN) 网络的组件&#xff1a;卷积层&#xff0c;池化层&#xff0c;激活层和全连接层。 CNN主要由以下层构造而成&#xff1a; 卷积层&#xff1a;Convolutional layer&#xff08;CONV&#xff09;池化层&#xff1a…

如何在windows系统部署Lychee网站,并结合内网穿透打造个人云图床

文章目录 1.前言2. Lychee网站搭建2.1. Lychee下载和安装2.2 Lychee网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4.公网访问测试5.结语 1.前言 图床作为图片集中存放的服务网站&#xff0c;可以看做是云存储的一部分&#xff0c;既可…

批量自动加好友,轻松拓展微信人脉圈子

在当今社交化的时代&#xff0c;拓展社交圈子已经成为许多人努力追求的目标。而微信作为中国人群中最主流的社交工具之一&#xff0c;更是成为人们拓展社交圈子的重要场所。在这样的背景下&#xff0c;有没有一种简单而高效的方式来扩大微信人脉圈子呢&#xff1f;答案是肯定的…