【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://xiahunao.cn/news/2815303.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

vue-router4 (六) 命名视图

命名视图可以使得同一级&#xff08;同一个组件&#xff09;中展示更多的路由视图&#xff0c;而不是嵌套显示&#xff0c; 命名视图可以让一个组件中具有多个路由渲染出口&#xff0c;这对于一些特定的布局组件非常有用。 应用场景&#xff1a; 比如点击login切换到组件A&am…

Random,随机函数

黑马程序员学习笔记 nextInt(n)&#xff1a; 只生成0~(n-1)之间的数字&#xff0c;不包括n 主要代码就三个; package com.zhang.random;import java.util.Random;public class RandomDemo1 {public static void main(String[] args) {//目标&#xff1a;掌握使用Random生成随…

进制转换md5绕过 [安洵杯 2019]easy_web1

打开题目 在查看url的时候得到了一串类似编码的东西&#xff0c;源码那里也是一堆base64&#xff0c;但是转换成图片就是网页上我们看见的那个表情包 ?imgTXpVek5UTTFNbVUzTURabE5qYz0&cmd 我们可以先试把前面的img那串解码了 解码的时候发现长度不够&#xff0c;那我们…

算法沉淀——动态规划之子序列问题(下)(leetcode真题剖析)

算法沉淀——动态规划之子序列问题 01.最长定差子序列02.最长的斐波那契子序列的长度03.最长等差数列04.等差数列划分 II - 子序列 01.最长定差子序列 题目链接&#xff1a;https://leetcode.cn/problems/longest-arithmetic-subsequence-of-given-difference/ 给你一个整数数…

springboot+vue实现oss文件存储

前提oss准备工作 进入阿里云官网&#xff1a;阿里云oss官网 注册 搜OSS&#xff0c;点击“对象存储OSS” 第一次进入需要开通&#xff0c;直接点击立即开通&#xff0c;到右上角AccessKey管理中创建AccessKey&#xff0c;并且记住自己的accessKeyId和accessKeySecret&#…

【数据结构与算法】回溯法解题20240229

【数据结构与算法】回溯法解题20240229 一、46. 全排列1、以[1,2,3]为例&#xff0c;抽象成树形结构2、回溯三部曲 二、LCR 084. 全排列 II1、以[1,1,2]为例&#xff0c;抽象成树形结构 三、面试题 08.07. 无重复字符串的排列组合四、面试题 08.08. 有重复字符串的排列组合 一、…

Java面试资料集合,只需一篇文章吃透Java多线程技术

前言 受到疫情影响我从过完年一直呆在家里&#xff0c;索性学点知识方便以后跳槽涨薪&#xff0c;于是从二月份开始学习阿里P8架构师纯手打的一份Java面经手册&#xff0c;没想到5月初我成功从我们三线的一个小公司跳槽进了腾讯&#xff0c;虽然等级不高&#xff0c;但是涨薪还…

【力扣hot100】刷题笔记Day15

前言 今天要刷的是图论&#xff0c;还没学过&#xff0c;先看看《代码随想录》这部分的基础 深搜DFS理论基础 深搜三部曲 确认递归函数、参数确认终止条件处理目前搜索节点出发的路径 代码框架 void dfs(参数) {if (终止条件) {存放结果;return;}for (选择&#xff1a;本节点…

Git教程-Git的基本使用

Git是一个强大的分布式版本控制系统&#xff0c;它不仅用于跟踪代码的变化&#xff0c;还能够协调多个开发者之间的工作。在软件开发过程中&#xff0c;Git被广泛应用于协作开发、版本管理和代码追踪等方面。以下是一个详细的Git教程&#xff0c;我们将深入探讨Git的基本概念和…

npm ERR! code ERESOLVE

1、问题概述&#xff1f; 执行npm install命令的时候报错如下&#xff1a; tangxiaochuntangxiaochundeMacBook-Pro stf % npm install npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resol…

C++ Primer 总结索引 | 第八章:IO库

1、IO类 1、已经使用过的IO类型和对象 都是 操纵char数据的。默认情况下&#xff0c;这些对象 都是关联到 用户的控制台窗口的 但是 不能仅从控制台窗口 进行IO操作&#xff0c;应用程序 需要 读写命名文件&#xff0c;使用IO操作 处理string中的字符 会很方便&#xff0c;此…

Netty入门指南:从零开始的异步网络通信

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 Netty入门指南&#xff1a;从零开始的异步网络通信 前言Netty简介由来&#xff1a;发展历程&#xff1a;异步、事件驱动的编程模型&#xff1a; 核心组件解析通信协议高性能特性异步编程范式性能优化与…

Linux零基础快速入门

Linux的诞生 Linux创始人:林纳斯 托瓦兹 Linux 诞生于1991年&#xff0c;作者上大学期间 因为创始人在上大学期间经常需要浏览新闻和处理邮件&#xff0c;发现现有的操作系统不好用,于是他决心自己写一个保护模式下的操作系统&#xff0c;这就是Linux的原型&#xff0c;当时他…

【MySQL】DCL

DCL英文全称是Data Control Language(数据控制语言)&#xff0c;用来管理数据库用户、控制数据库的访问权限。 1. 管理用户 在MySQL数据库中&#xff0c;DCL&#xff08;数据控制语言&#xff09;是用来管理用户和权限的语句集合。通过DCL语句&#xff0c;可以创建、修改、删…

leetcode 重复的子字符串

前要推理 以abababab为例&#xff0c;这里最主要的就是根据相等前后缀进行推导 s [ 0123 ] 如 t【 0123 】 f 【01 23 】 后两个分别是前后缀&#xff0c;第一个是总的字符串&#xff0c;然后可以推导 //首先还是算出…

Spring的定时任务不生效、不触发,一些可能的原因,和具体的解决方法。

1 . 未在启动类上加 EnableScheduling 注解 原因&#xff1a;未在Spring Boot应用主类上添加EnableScheduling注解或未在XML配置文件中配置定时任务的启用。解决方法&#xff1a;确保在应用的配置类上添加EnableScheduling注解&#xff0c;启用定时任务。 2 . cron 表达式书写…

P4859 已经没有什么好害怕的了(二项式反演+dp)

题录&#xff1a;P4859 已经没有什么好害怕的了 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 思路: 代码&#xff1a; #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<string> #include<cstring> #include<cmath> #include<ctim…

Kubernetes剖析

Kubernetes剖析 前言 ​ 容器技术这样一个新生事物&#xff0c;完全重塑了整个云计算市场的形态。它不仅催生出了一批年轻有为的容器技术人&#xff0c;更培育出了一个具有相当规模的开源基础设施技术市场。 ​ 在这个市场里&#xff0c;不仅有 Google、Microsoft 等技术巨擘…

【GPTs分享】GPTs分享之Photo Multiverse,不唱、跳、RAP的坤坤能叫坤坤吗

今日GPTs分享&#xff1a;Photo Multiverse。Photo Multiverse 是一款基于先进人工智能技术的创意辅助工具&#xff0c;专为艺术家和创意人士设计&#xff0c;以探索和创造多元宇宙中的视觉艺术。它通过结合古老的艺术神秘主义和现代技术&#xff0c;帮助用户将他们的想象力变为…

linux gdb 调试工具

1.写程序 首先&#xff0c;我们先写出一个 .c 或者.cpp程序 如 然后 gcc -g hello.c -o hello 或者 g -g hello.cpp -o hello &#xff08;-g&#xff09;要加 2. gdb调试 用 gdb &#xff08;可执行程序&#xff0c;如hello&#xff09; 进入之后&#xff0c;有…