gRPC学习笔记

课程链接:https://www.bilibili.com/video/BV1S24y1U7Xp

gRPC示例链接:https://gitee.com/huangheng179/golang-grpc-example

微服务架构

单体架构

  1. 一旦某个服务宕机,会引起整个应用不可用,隔离性差
  2. 只能整体应用进行伸缩,浪费资源,可伸缩性差
  3. 代码耦合在一起,可维护性差

微服务架构 解决单体架构的弊端,同时引入了新的问题

  1. 代码冗余
  2. 服务于服务之间存在调用关系

服务与服务拆分后,服务和服务之间发生的是进程间的调用,服务器间的调用。于是就需要发起网络调用,网络调用我们立马能想起Http,但是在微服务架构中,Http虽然便捷方便,但性能较低,这时候就需要引入RPC(远程过程调用),通过自定义协议发起TCP调用,来加快传输效率。

  • HTTP 方便便捷 但是性能较低
  • RPC是在TCP协议的基础上,自定义的网络协议,传输效率高,性能更高。

RPC(Remote Procedure Call,远程过程调用)是一种协议,用来屏蔽分布式计算中的各种调用细节,使得你可以像本地调用一样直接调用一个远程函数。gRPC是RPC的一种具体落地方案。

gRPC简介

gRPC是一个高性能、开源的通用的RPC框架。

在gRPC中,调用方称为cilent,被调用方称为server。

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

server在定义好了这些服务、这些方法后,gRPC会屏蔽底层的细节,cilent需要直接调用定义好的方法,就可以拿到预期的返回结果。

所谓的“服务定义”和“接口”的语义是相似的。双方约定好接口,然后在server端实现这个接口,cilent调用这个接口的代理对象。至于其他细节,交给gRPC。

gRPC是语言无关的,可以使用C++作为server,使用Golang、Java等作为cilent。

Protobuf简介

在这里插入图片描述

如上图所示,gRPC使用了Protocal Buffss(Protobuf),这是谷歌开源的一套成熟的数据结构序列化机制。

  • 序列化:将对象转化为二进制串

  • 反序列化:将二进制串转化为对象

Protobuf的优势

  1. 序列化后体积相比于json和xml更小,适合网络传输
  2. 支持跨平台多语言
  3. 消息格式升级和兼容性很好
  4. 序列化和反序列化速度快

gRPC相关的安装过程

安装Protobuf编译器

  1. 下载解压, 下载地址:https://github.com/protocolbuffers/protobuf/releases,并配置环境变量
  2. 输入protoc命令查看是否安装成功

安装gRPC的核心库

  1. go get google.golang.org/grpc

安装Protobuf对应golang的代码生成工具protoc-gen-go

  • go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
  • go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

go基础之go getgo install

  1. go get 主要用于获取、更新和安装远程依赖包。它会自动从远程代码库(如 GitHub、GitLab)下载依赖包,并将其安装到 GOPATH目录中。当执行 go get 命令时,它会下载指定的包及其依赖项,并将其放置在正确的目录结构中,以供项目引用。通常,go get 会自动安装依赖项,无需手动执行 go install

  2. go install 则用于编译并安装 Go 语言的可执行程序。它将 Go 代码编译成二进制文件,并将其安装到 GOPATH的 bin 目录中,以供后续执行。当执行 go install 命令时,它会在当前包的目录中执行编译过程,并将生成的可执行文件放置在 bin 目录中。通过 go install 安装的可执行文件可以通过命令行直接运行,无需指定文件路径。

Protobuf的示例

编写Protobuf约束文件

syntax = "proto3";

// option go_package 用于指定生成的 Go 代码应该放在哪个 Go 包(package)中
// .:这表示生成的 Go 代码应该位于与 .proto 文件相同的目录中(即当前目录)。如果你想要生成的代码位于不同的目录中,你可以指定一个相对路径或绝对路径。
// service:这是 Go 包的名字。当 protoc 编译器生成 Go 代码时,它会在生成的 .pb.go 文件的顶部使用 package service 这一行来声明包名。
option go_package = ".;service";

service SayHello{
	rpc SayHello(HelloRequest) returns (HelloResponse){}
}

// 注意 变量后的等于号是用于定义这个变量在message中的位置,而不是赋值。
message HelloRequest{
	string requestName = 1;
}

message HelloResponse{
	string responseMsg = 1;
}

根据Protobuf约束文件生成*.pb.go*_grpc.pb.go文件

protoc --go_out=. hello.proto		# 生成go相关文件
# 这条命令用于生成与 hello.proto 文件相关的 Go 结构体、枚举等。具体来说,它会读取 hello.proto 文件,并基于其中的消息定义(message)、服务定义(service)等生成相应的 Go 代码。这些生成的 Go 代码通常包含用于序列化和反序列化 Protocol Buffers 数据的函数和方法。
protoc --go-grpc_out=. hello.proto 	# 生成rpc相关文件
# 这条命令用于生成与 gRPC 相关的 Go 代码。它读取 hello.proto 文件中的服务定义,并生成实现 gRPC 客户端和服务器所需的 Go 接口和辅助函数。这包括客户端和服务器的桩(stubs)代码,用于进行 RPC 调用和响应。

Protobuf语法介绍

消息定义

message关键字

message: protobuf中定义一个消息类型式是通过关键字 message字段指定的。消息就是需要传输的数据格式的定义

message关键字类似于C++中的class, JAVA中的class, go中的struct

在消息中承载的数据分别对应于每一个字段,其中每个字段都有一个名字和一种类型

proto文件中可以定义多个消息类型

字段规则

required:消息体中必填字段,不设置会导致编码异常。在protobuf2中使用,在protobuf3中被删去

optional:消息体中可选字段。protobuf3没有了required、optional说明关键字,都默认为optional。

repeated:消息体中可重复字段,重复的值的顺序会被保留在go中重复的会被定义为切片。

消息号

在消息体的定义中,每个字段都必须要有一个唯一的标识号,标识号是[1,2^29-1]范围内的一个整数

嵌套消息

可以在其他消息类型中定义、使用消息类型,在下面的例子中,Person消息就定义在Personinfo消息内如

message PersonInfo{
	message Person{
		string name = 1;
		int32 height = 2;
		repeated int32 weight = 3;
	}
	repeated Person info = 1;
}

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

message PersonMessage{
	PersonInfo.Person info = 1;
}

服务定义

可以使用service关键词定义一个RPC服务接口。

service SearchService {  
    rpc Search1(SearchRequest) returns (SearchResponse);  
    rpc Search2(SearchRequest) returns (SearchResponse);  
}

golang-gRPC示例

一个包含客户端代码、服务端代码和Protobuf文件的完整实例:https://gitee.com/huangheng179/golang-grpc-example

go基础之packagemodule

  1. package(包)是Go语言中的基础组织单位,它用于组成代码结构和解决命名隔离问题。每个包都由一系列相关的Go代码文件构成,这些文件在文件系统上位于同一个目录下。包是代码模块化和代码复用的关键,通过包,开发者可以将相关的函数、类型、变量等组织在一起,并通过包名来访问它们。此外,Go语言提供了很多内置包,如fmt,同时开发者也可以根据自己的需要创建自定义包。在Go语言中,包是import的单位,import语句写在每个Go源码文件的开头。

  2. module(模块)是一个集合了许多包的更大单位,它主要解决的问题是版本控制和包分发。一个模块可以包含一个或多个包,并且每个模块都有一个明确的版本。模块是源代码更替和版本控制的单元,它使得开发者能够更方便地管理项目的依赖关系。在Go 1.11及以后的版本中,引入了模块支持,通过go mod命令来管理项目的依赖和包。模块是require的单位,require语句写在go.mod文件中。

服务端代码

  1. 创建gRPC Server对象grpcServer

  2. 将服务注册到gRPC Server的内部注册中心

    这样可以在接收到请求时,通过内部的服务发现,发现该服务端接口并转接进行逻辑处理

  3. 创建Listen,监听TCP端口

  4. grpcServer开始lis.Accept,直到Stop

客户端代码

  1. 创建与给定目标(服务端)的连接交互
  2. 创建客户端对象
  3. 发送RPC请求,等待同步响应,得到回调后返回响应结果
  4. 输出响应结果

gRPC的认证-安全传输

  • SSL/TLS认证方式(采用http2协议)
  • 基于Token的认证方式(基于安全连接)
  • 自定义的身份认证
  • 不采用任何措施的连接,这是不安全的连接(默认采用http1)
  • 27
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值