当前位置: 首页 > news >正文

gRPC简介

grpc简介

grpc介绍可以参考官网。无论是rpc还是grpc,可以这样理解,都知道过去使用的单单体架构,而在2011年5月威尼斯的一个软件架构会议上提出了微服务架构,围绕业务功能进行组织(organized around business capability),不再是以前的纵向切分,而改为按业务功能横向划分,一个微服务最好由一个小团队针对一个业务单元来构建。
在这里插入图片描述
所以服务和服务之间存在调用关系,服务中之间使用http调用,发现性能太差,使用了一种新的通信方式,这个通信方式称为rpc客户端和服务端沟通的过程如下:

  1. 客户端发送数据(以字节流的方式)编码
  2. 服务端接受并解析,根据约定执行什么然后把结果返回给客户,解码
    那RPC的发展,RPC远程调用总体而言:
  3. rpc就是上述的过程封装下,时期操作更加优化
  4. 使用一些大家都认可的协议,使其规范化
  5. 做成一些框架,直接或间接的产生利益,这个就是grpc

grpc是基于“服务定义”的思想,简单的来说,就是通过某种方式描述一个服务,这种描述与语言无关,在这个“服务定义”的过程中,描述了提供的服务名是什么,有哪些方法可以被调用,这些方法有哪些参数,返回参数是什么

grpc调用方称之为client,服务方为server。也就是说定义好了这些方法和服务之后,grpc会屏蔽底层的细节,client只需要调用定义好的防范,就能返回预期的结果,对server段来说,还需要实现定义的方法。

proto创建

这里结合grpc-study实例介绍,按照如下目录创建工程和文件,仅有hello.proto中存在代码
在这里插入图片描述

proto是一种语法,类似go中约定变量定义var name string一样,python中variable=1一样的语法规定。proto中也有自己的语法,比如使用message,使用service关键字, hello.proto代码如下:

syntax = "proto3";// 这部分内容是关于最后生成的go文件的是放在哪个目录哪个包中的, "."代表在当前目录生成,service代表了生成go文件的包名是service
option go_package=".;service";// 这里定义一个服务,这个份服务需要有一个方法,这个方法可以接受客户端的参数请求,再返回服务端的响应,这个方法是以rpc,就像func标记一个函数一行,这个rpc标记的是一个rpc的方法
// 其实可以看出,定义了一个service,称之为SayHello,这个服务有一个rpc的方法,名为SayHello
// 这个方法会发送一个HelloRequest,然后返回一个 HelloResponse
service SayHello {rpc SayHello(HelloRequest) returns (HelloResponse) {}
}// 既然是约定的一些规则,这里需要使用message关键字顶一个结构体,这个message类似go中的struct
// 这里比较特殊的是变量后的赋值,这里不是赋值,而是在定义这个变量在这个message中的位置,可以理解为显示的定义了该参数在message数组或者结构体的索引位置
// 最终生成代码的时候,就会根据标识号来生成对应的位置,如requestName在第一个位置就会生成在第一个
message HelloRequest {string requestName = 1;
}message HelloResponse {string response = 1;
}// 以上是一个约束规则,就是一个语法规定

terminal切换到 grpc-service下

grpc-study % cd hello-server\proto

切换该目录后,在和*.proto同级目录执行如下命令

protoc --go_out=. hello.proto  // 使用go_out生成需要的go语言的文件
protoc --go-grpc_out=. hello.proto // 使用go_out生成需要的rpc语言的文件

执行完成后,在proto下新增两个文件如下所示
在这里插入图片描述
对于远程过程调用,就使用的grpc中的代码。在这里插入图片描述
所以关于proto的总结如下:

  1. 创建工程项目,设置文件分层
  2. 编写proto文件
  3. (切换目录)使用go-out生成pb.go,使用go-grpc_out命令生成gprc.pb.go文件

proto文件介绍

message

message:protobul定义了一个消息类型是通过关键字message字段指定,消息就是要传输的数据格式的定义,message类似go中的struct,在消息中承载的数据分别对应的是一个字段,每个字段都有一个名字和一种类型。每个字段有一些规则:

  1. required:消息体中的必填字段,不设置时会导致编码异常,在protobf2中使用,在protobuf3中删除
  2. optional:消息体中的可选字段,protobuf3中取消了required和optional等说明关键字,默认都是optional
  3. repeated:消息中的可重复字段,重复的值的顺序会被保留在go中重复的会被定义为切片,使用repeadted可以理解为类似数组
    每个字段都必须有一个唯一的标识好,一般不建议一个消息号中超过15,当然消息也可以嵌套定义
message PersonInfomation {message Person {string name = 1;int32 height = 2;repeated int32 age = 3;}repeated Person info = 1;
}

如果要在父消息类型的外部重用这个消息类型,需要PersonInformation.Person的形式使用它,如:

message PersonMessage {PersonInformation.Person info  = 1;
}

既然是用于微服务,如果想要将消息类型用在RPC的系统中,可以在**.proto文件中定义一个RPC服务接口,protocol buffer编译器将会更具所选择的不同语言生成服务接口代码和存根

service SearchService {// rpc 服务函数名 (参数名)返回 (返回参数)rpc Search(SearchRquest) returns (SearchResponse)
}

这样就定义了了RCP的服务,该方法接受SearchRequest请求和SearchResponse响应.所以这个*.proto文件中的格式只是一个约定规定,就像go的函数使用func声明是一个函数,*.proto中也有自己的一些约束。有了这些约束之后,客户端和服务端都是去调用这些接口的,有了这些约束之后,grpc可以帮助我们去寻路,用什么方法写的,就调用什么方法就可以。

服务端实现

有了上面的*.proto的约束之后,就可以遵循该声明实现服务端的接口调用,服务端实现如下:

  • 创建gRPC Server对象,我们可以理解他是Server端的抽象对象
  • 将Server(包含需要被调用的服务端接口)注册到gRPC Server的内部注册中心,这样可以在服务端接受请求时,通过内部的服务发现,发现该服务器接口并转接进行逻辑处理
  • 创建Listen,监听TCP端口
  • gRPC Server开始lis.Accept,直到Stop
    上面定义了server中的方法,这里来具体实现,在serverice下的main.go中
package mainimport ("context""fmt""google.golang.org/grpc"pb "grpc-study/hello-server/proto""net"
)// hello server
type server struct {pb.UnimplementedSayHelloServer
}func (s *server) SayHello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloResponse, error) {fmt.Printf("hello" + req.RequestName)return &pb.HelloResponse{Response: "hello" + req.RequestName}, nil
}func main() {//	开启端口监听listen, _ := net.Listen("tcp", "9090")//	把这个服务暴露其他服务使用grpcServer := grpc.NewServer()//在grpc服务端中去注册自己编写的服务pb.RegisterSayHelloServer(grpcServer, &server{})//创建服务完成后,启动该服务err := grpcServer.Serve(listen)if err != nil {fmt.Printf("failed to server: %", err)return}
}// 如何实现具体逻辑呢,在grpc.pb.go中找到源码,实现对应的方法逻辑就行了

客户端实现

有了上面的*.proto的约束之后,就可以遵循该声明实现服务端的接口调用,服务端实现如下:

  • 创建于给定目标(服务端)的连接交互
  • 创建server的客户端对象
  • 发送RPC对象,等待同步响应,得到回调后返回响应结果
  • 输出响应结果
package mainimport ("context""fmt""google.golang.org/grpc""google.golang.org/grpc/credentials/insecure"pb "grpc-study/hello-server/proto""log"
)func main() {// 连接打server端,次数禁用安全传输,没有加密和验证conn, err := grpc.Dial("127.0.0.1:9090", grpc.WithTransportCredentials(insecure.NewCredentials()))if err != nil {log.Fatalf("did not connect: %v", err)}defer conn.Close()//建立连接client := pb.NewSayHelloClient(conn)// 执行rpc调用(这个方法时在服务器端来实现并返回结果)resp, _ := client.SayHello(context.Background(), &pb.HelloRequest{RequestName: "zhiyu"})fmt.Println(resp.GetResponse())
}

先执行server中的main.go,再执行执行client中的main.go,检查执行结果,未来只要能找到"127.0.0.:9090"这个地址就可以调用到服务并可以拿到返回结果。goland IDE界面分屏执行两个main.go函数
在这里插入图片描述

这里注意到client/main.go中

func main() {// 连接打server端,此处禁用安全传输,没有加密和验证conn, err := grpc.Dial("127.0.0.1:9090", grpc.WithTransportCredentials(insecure.NewCredentials()))if err != nil {log.Fatalf("did not connect: %v", err)}

只要能访问到该地址信息,就可以拿到返回结果,因此这种是不安全的,所以需要进行加密+安全传输。
经过前文的学习,我们直到gRPC是一个C/S模型,需要开户客户端和服务端,客户端和服务端需要达成协议,使用某一个确认的传输协议来传输数据,gPRC通过默认使用protobuf作为传输协议,当然也可以使用其他的自定义协议创建,如你可以使用xml。接着再看grpc官网中的这个示意图,就可以如下表示:
在这里插入图片描述

客户端和服务端通信之前,客户端如何知道自己的数据发送给哪个明确的服务端呢?反过来,服务端是如何知道将数据返回给谁呢,这个就需要gRPC认证。
此处说到的认证,不是用户的身份认证,而是指多个server和多个client之间,如何识别对方是谁,并且可以安全的进行数据传输,可以通过如下的几种方式:

  • SSL/TLS认证方式(采用http2协议)
  • 基于Token的认证方式(基于安全连接)
  • 不采用任何措施的连接,这是不安全的连接(默认采用http1)
  • 自定义的身份认证
    客户端和服务端之间调用,我们可以通过加入证书的方式,实现调用的安全性
    TLS(Transport Layer Security,安全传输层),TLS是建立在传输层TCP协议之上的协议,服务于应用层,它的前身是SSL(Secure Socket Layeer,
    安全套接字层),它实现了将应用层的报文进行加密后再交由TCP进行传输的功能。
    TLS协议主要解决如下三个网络安全问题。
  1. 保密(message privacy),保密通过加密encryption实现,所有信息都加密传输,第三方无法嗅探;
  2. 完整性(message integrity),通过MAC校验机制,一旦被篡改,通值双方会立刻发现;
  3. 认证(mutual authentication),双方认证,双方都可以配备证书,防止身份被冒充
    生存环境可以购买证书或者使用一些平台发放的证书
  • key:服务器上的私钥文件,用于对发送给客户端数据的加密,以及对从客户端接受到数据的解密
  • csr:证书签名请求文件,用于提交给证书颁发机构(CA)对证书签名。
  • crt:由证书颁发机构(CA)签名后的证书,或者是开发者自签名的证书,包含证书持有人的信息,持有人的公钥,以及签署者的签名等信息
  • pem:是基于Base64编码的证书格式,扩展名包括PEM、CRT和CER

SSL/TLS认证方式

首先通过openssl生成证书和私钥,关于认证方式参考:https://www.kuangstudy.com/bbs/1604044550878703617

  1. 官网下载:https://www.openssl.org/source/ ,便捷版安装包http://slproweb.com/products/Win320penSSL.html
  2. 我们使用便捷版安装包,一直下一步即可
  3. 配置环境变量 D:\Environment\OpenSSL-Win64\bin
  4. 命令行测试 openssl

生成证书步骤如下,mac安装ssl参考:https://www.freesion.com/article/7165613046/

#1、生成私钥
openssl genrsa -out server.key 2048
#2、生成证书全部回车即可,可以不填
openss1 req -new -x509 -key server.key -out server.crt -days 36500
#国家名称
Country Name (2 letter code) [AU] :CN
#省名称
State or Province Name (full name) [Some-State]:GuangDong
#城市名称
Locality Name (eg, city) []:Meizhou
#公司组织名称
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Xuexiangbar
#部门名称
Organizational Unit Name (eg, section) []:go
#服务器or网站名称
Common Name
# 邮件
(e.g. server FQDN or YOUR name) []:kuangstudy
Email Address []:24736743@qq.com# 3、生存csr
openssl req -new -key server.key -out server.cs
#更改openssl.cnf (Linux 是openssl.cfg)
#1)复制一份你安装的openssl的bin目录里面的openssl.cnf 文件到你项目所在的目录
#2)找到[CA_default],打开 copy_extensions=copy(就是把前面的#去掉)
#3)找到[req],打开 req_extensions=v3_req # Thhe extensions to add to a certificate request
#4)找到[v3_req],添加 subjectAltName=@alt_namnes
#5)添加新的标签[alt_names],和标签字段
DNS.1 = *.zhiyu.com

这个就是对应未来通过zhiyu.com这个域名去访问才能同意,相当于是一个安全性的校验,客户端发起请求的时候需要携带该域名,这就是安全机制校验

相关文章:

gRPC简介

grpc简介 grpc介绍可以参考官网。无论是rpc还是grpc,可以这样理解,都知道过去使用的单单体架构,而在2011年5月威尼斯的一个软件架构会议上提出了微服务架构,围绕业务功能进行组织(organized around business capability)&#xf…...

《MySQL系列-InnoDB引擎25》表-InnoDB逻辑存储结构

InnoDB逻辑存储结构 从InnoDB存储引擎的逻辑存储结构看,所有数据都被逻辑地存放在一个空间中,称之为表空间(tablespace)。表空间又由段(segment)、区(extent)、页(page)组成。页在一些文档中有时也称为块(block),InnoDB存储引擎的逻辑存储结构…...

YOLOv8之C2f模块——与YOLOv5的C3模块对比

一、源码对比 YOLOv8完整工程代码下载:ultralytics/ultralytic   C2f模块源码在ultralytics/nn/modules.py下,源码如下: class C2f(nn.Module):# CSP Bottleneck with 2 convolutionsdef __init__(self, c1, c2, n1, shortcutFalse, g1, e…...

动态规划实例——换零钱的方法数(C++详解版)

原写了 Java 版本的如何求解换钱的方法数,近期进行了一些细节上的补充,以及部分错误更正,将语言换为了 C 语言。 基础题目 假设你现在拥有不限量的 1 元、5 元、10 元面值纸币,路人甲希望找你换一些零钱,路人甲拿出的…...

linux c

射频驱动 管理硬件设备、分配系统资源 内核由中断服务程序 调度程序 内存管理程序 网络和进程间进程通信程序 linux支持动态加载内核模块 支持多处理smp机制 内核可以抢占preemptive linux系统拥有多个发行版,可能由一个组织 公司和个人发行 VGA兼容或者更…...

第十三章 系统错误消息 - 一般系统错误消息 S - Z

文章目录第十三章 系统错误消息 - 一般系统错误消息 S - Z第十三章 系统错误消息 - 一般系统错误消息 S - Z 错误代码描述<SUBSCRIPT>下标值不合法或Global引用过长。<SWIZZLE FAIL>打开了一个oref&#xff0c;然后试图在另一个无法引用的相关对象中进行搅拌。这可…...

移动web基础

初始缩小&#xff1a;布局视口大于视觉视口 初始放大&#xff1a;布局视口小于视觉视口 布局视口等于视觉视口&#xff08;这种动作行为叫做理想视口&#xff09; <meta name"viewport" content"width375" /> <meta name"viewport"…...

MyBatis和MyBatis_Plus有什么区别【面试常考题】

MyBatis和MyBatis_Plus的区别 MyBatis_Plus MyBatis_Plus 是一个 MyBatis 的增强工具&#xff0c;只是在 MyBatis 的基础上增强了却没有做改变&#xff0c;MyBatis-Plus支持所有MyBatis原生的特性&#xff0c;所有引入MyBatis-Plus不会对现有的MyBatis框架产生任何影响。 MyBa…...

华为OD机试用Python实现 -【统一限载货物数最小值】(2023-Q1 新题)

华为OD机试题 华为OD机试300题大纲统一限载货物数最小值题目描述输入描述输出描述说明示例一输入输出说明示例二输入输出说明Python 代码实现算法逻辑华为OD机试300题大纲 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查…...

Vue入门小练习

文章目录Hello VueVue文本指令Vue属性绑定Vue双向绑定Vue事件绑定Vue猜数字Vue简单计算器Vue简单计算器升级版Vue循环遍历Vue员工列表练习Vue小练习Vue显示隐藏相关使用一些简单的小案例来熟悉Vue的基本使用方法 Hello Vue <!DOCTYPE html> <html lang"en"…...

Oracle-09-集合运算符篇

2022年4月13日23:01:25 通过本章学习,您将可以:1、描述 SET 操作符2、将多个查询用 SET 操作符连接组成一个新的查询目录 🏆一、SET OPERATORS ⭐️1.1、UNION /UNION ALL ⭐️1.2、INSTERSECT ⭐️1.3、MINUS dz...

获取浏览器(服务端)请求中特定的Cookie

有必要解释一下HttpServletRequest接口&#xff0c;因为我们需要从它里面获取Cookie。 HttpServletRequest HttpServletRequest是一个Java接口&#xff0c;提供了访问HTTP请求信息的方法&#xff0c;例如HTTP方法、请求URI、头部、参数和会话属性。它是Java Servlet API的一部…...

c++11 标准模板(STL)(std::unordered_set)(九)

定义于头文件 <unordered_set>template< class Key, class Hash std::hash<Key>, class KeyEqual std::equal_to<Key>, class Allocator std::allocator<Key> > class unordered_set;(1)(C11 起)namespace pmr { templat…...

python实战应用讲解-【实战应用篇】文件操作(附python示例代码)

目录 知识储备 使用 python-libarchive-c 模块 创建压缩文件 解压文件 查看信息...

OpenCV-Python系列(二)—— 图像处理(灰度图、二值化、边缘检测、高斯模糊、轮廓检测)

一、【灰度图、二值化】 import cv2 img cv2.imread("lz2.png") gray_img cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度图 # 二值化&#xff0c;(127,255)为阈值 retval,bit_img cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY) cv2.imshow(photo1,im…...

ccc-台大林轩田机器学习基石-hw1

文章目录Question1-14Question15-PLAQuestion16-PLA平均迭代次数Question17-不同迭代系数的PLAQuestion18-Pocket_PLAQuestion19-PLA的错误率Question20-修改Pocket_PLA迭代次数Question1-14 对于有明确公式和定义的不需要使用到ml 智能系统在与环境的连续互动中学习最优行为策…...

hadoop03-MapReduce【尚硅谷】

大数据学习笔记 MapReduce 一、MapReduce概述 MapReduce是一个分布式运算程序的编程框架&#xff0c;是基于Hadoop的数据分析计算的核心框架。 MapReduce处理过程为两个阶段&#xff1a;Map和Reduce。 Map负责把一个任务分解成多个任务&#xff1b;Reduce负责把分解后多任务处…...

测牛学堂:软件测试python学习之异常处理

python的捕获异常 程序在运行时&#xff0c;如果python解释器遇到一个错误&#xff0c;则会停止程序的执行&#xff0c;并且提示一些错误信息&#xff0c;这就是异常。 程序停止执行并且提示错误信息&#xff0c;称之为抛出异常。 因为程序遇到错误会停止执行&#xff0c;有时…...

图神经网络--图神经网络

图神经网络 图神经网络图神经网络一、PageRank简介1.1互联网的图表示1.2PageRank算法概述1.3求解PageRank二、代码实战2.1引入库2.2加载数据&#xff0c;并构建图2.3计算每个节点PageRank重要度2.4用节点尺寸可视化PageRank值一、PageRank简介 PageRank是Google最早的搜索引擎…...

React useCallback如何使其性能最大化?

前言 React中最让人畅谈的就是其带来的灵活性&#xff0c;可以说写起来非常的舒服。但是也就是它的灵活性太强&#xff0c;往往让我们忽略了很多细节的地方&#xff0c;而就是这些细节的东西能进行优化&#xff0c;减小我们的性能开销。可以说刚学React和工作几年后写React的代…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

【51单片机】4. 模块化编程与LCD1602Debug

1. 什么是模块化编程 传统编程会将所有函数放在main.c中&#xff0c;如果使用的模块多&#xff0c;一个文件内会有很多代码&#xff0c;不利于组织和管理 模块化编程则是将各个模块的代码放在不同的.c文件里&#xff0c;在.h文件里提供外部可调用函数声明&#xff0c;其他.c文…...

Springboot 高校报修与互助平台小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;高校报修与互助平台小程序被用户普遍使用&#xff0c;为…...

比较数据迁移后MySQL数据库和ClickHouse数据仓库中的表

设计一个MySQL数据库和Clickhouse数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...