gRPC简介
grpc简介
grpc介绍可以参考官网。无论是rpc还是grpc,可以这样理解,都知道过去使用的单单体架构,而在2011年5月威尼斯的一个软件架构会议上提出了微服务架构,围绕业务功能进行组织(organized around business capability),不再是以前的纵向切分,而改为按业务功能横向划分,一个微服务最好由一个小团队针对一个业务单元来构建。

所以服务和服务之间存在调用关系,服务中之间使用http调用,发现性能太差,使用了一种新的通信方式,这个通信方式称为rpc客户端和服务端沟通的过程如下:
- 客户端发送数据(以字节流的方式)编码
- 服务端接受并解析,根据约定执行什么然后把结果返回给客户,解码
那RPC的发展,RPC远程调用总体而言: - rpc就是上述的过程封装下,时期操作更加优化
- 使用一些大家都认可的协议,使其规范化
- 做成一些框架,直接或间接的产生利益,这个就是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的总结如下:
- 创建工程项目,设置文件分层
- 编写proto文件
- (切换目录)使用go-out生成pb.go,使用go-grpc_out命令生成gprc.pb.go文件
proto文件介绍
message
message:protobul定义了一个消息类型是通过关键字message字段指定,消息就是要传输的数据格式的定义,message类似go中的struct,在消息中承载的数据分别对应的是一个字段,每个字段都有一个名字和一种类型。每个字段有一些规则:
- required:消息体中的必填字段,不设置时会导致编码异常,在protobf2中使用,在protobuf3中删除
- optional:消息体中的可选字段,protobuf3中取消了required和optional等说明关键字,默认都是optional
- 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协议主要解决如下三个网络安全问题。
- 保密(message privacy),保密通过加密encryption实现,所有信息都加密传输,第三方无法嗅探;
- 完整性(message integrity),通过MAC校验机制,一旦被篡改,通值双方会立刻发现;
- 认证(mutual authentication),双方认证,双方都可以配备证书,防止身份被冒充
生存环境可以购买证书或者使用一些平台发放的证书
- key:服务器上的私钥文件,用于对发送给客户端数据的加密,以及对从客户端接受到数据的解密
- csr:证书签名请求文件,用于提交给证书颁发机构(CA)对证书签名。
- crt:由证书颁发机构(CA)签名后的证书,或者是开发者自签名的证书,包含证书持有人的信息,持有人的公钥,以及签署者的签名等信息
- pem:是基于Base64编码的证书格式,扩展名包括PEM、CRT和CER
SSL/TLS认证方式
首先通过openssl生成证书和私钥,关于认证方式参考:https://www.kuangstudy.com/bbs/1604044550878703617
- 官网下载:https://www.openssl.org/source/ ,便捷版安装包http://slproweb.com/products/Win320penSSL.html
- 我们使用便捷版安装包,一直下一步即可
- 配置环境变量 D:\Environment\OpenSSL-Win64\bin
- 命令行测试 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)…...
《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,然后试图在另一个无法引用的相关对象中进行搅拌。这可…...
移动web基础
初始缩小:布局视口大于视觉视口 初始放大:布局视口小于视觉视口 布局视口等于视觉视口(这种动作行为叫做理想视口) <meta name"viewport" content"width375" /> <meta name"viewport"…...
MyBatis和MyBatis_Plus有什么区别【面试常考题】
MyBatis和MyBatis_Plus的区别 MyBatis_Plus MyBatis_Plus 是一个 MyBatis 的增强工具,只是在 MyBatis 的基础上增强了却没有做改变,MyBatis-Plus支持所有MyBatis原生的特性,所有引入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接口,因为我们需要从它里面获取Cookie。 HttpServletRequest HttpServletRequest是一个Java接口,提供了访问HTTP请求信息的方法,例如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) # 灰度图 # 二值化,(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是一个分布式运算程序的编程框架,是基于Hadoop的数据分析计算的核心框架。 MapReduce处理过程为两个阶段:Map和Reduce。 Map负责把一个任务分解成多个任务;Reduce负责把分解后多任务处…...
测牛学堂:软件测试python学习之异常处理
python的捕获异常 程序在运行时,如果python解释器遇到一个错误,则会停止程序的执行,并且提示一些错误信息,这就是异常。 程序停止执行并且提示错误信息,称之为抛出异常。 因为程序遇到错误会停止执行,有时…...
图神经网络--图神经网络
图神经网络 图神经网络图神经网络一、PageRank简介1.1互联网的图表示1.2PageRank算法概述1.3求解PageRank二、代码实战2.1引入库2.2加载数据,并构建图2.3计算每个节点PageRank重要度2.4用节点尺寸可视化PageRank值一、PageRank简介 PageRank是Google最早的搜索引擎…...
React useCallback如何使其性能最大化?
前言 React中最让人畅谈的就是其带来的灵活性,可以说写起来非常的舒服。但是也就是它的灵活性太强,往往让我们忽略了很多细节的地方,而就是这些细节的东西能进行优化,减小我们的性能开销。可以说刚学React和工作几年后写React的代…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
