gRPC(三)基础:gRPC快速入门

简介: Protobuf 是 Google 的序列化/反序列化协议,可以轻松定义服务和自动生成客户端库。gRPC 使用此协议作为其接口定义语言 (IDL) 和序列化工具集。

前言


个人网站:https://linzyblog.netlify.app/

示例代码已经上传到github:点击跳转

gRPC官方文档:点击跳转


一、gRPC概述


1、什么是gRPC?


gRPC 是一个强大的开源 RPC(远程过程调用)框架,用于构建可扩展且快速的 API。它允许客户端和服务器应用程序透明地通信并开发连接的系统。gRPC框架依赖 HTTP/2、协议缓冲区和其他现代技术堆栈来确保最大的 API 安全性、性能和可扩展性。


在 gRPC 中,客户端应用程序可以直接调用不同机器上的服务器应用程序上的方法,就像是本地对象一样,更容易创建分布式应用程序和服务。


与许多 RPC 系统一样,gRPC 基于定义服务的思想,指定可以远程调用的方法及其参数和返回类型。在服务端,服务端实现这个接口并运行一个 gRPC 服务器来处理客户端调用。在客户端,客户端有一个存根(自动生成的文件),它提供与服务器相同的方法。


65739071138f4cbeb98dec3befa78154.png


2、gRPC 的历史


2015 年,Google 开发了 gRPC 作为 RPC 框架的扩展,以链接使用不同技术创建的许多微服务。最初,它与 Google 的内部基础设施密切相关,但后来,它被开源并标准化以供社区使用。在其发布的第一年,顶级组织利用它来支持从微服务到 Web、移动和物联网的用例。并在 2017 年因越来越受欢迎而成为云原生计算基金会(CNCF)孵化项目。


3、使用Protobuf


Protobuf 是 Google 的序列化/反序列化协议,可以轻松定义服务和自动生成客户端库。gRPC 使用此协议作为其接口定义语言 (IDL) 和序列化工具集。


  • 客户端和服务器之间的 gRPC 服务和消息在 proto 文件中定义。


  • Protobuf 编译器 protoc 生成客户端和服务器代码,在运行时将 .proto 文件加载到内存中,并使用内存中的模式来序列化/反序列化二进制消息。


  • 代码生成后,每条消息都会在客户端和远程服务之间进行交换。


为什么使用Protobuf?

使用 Protobuf 进行解析需要更少的 CPU 资源,因为数据被转换为二进制格式,并且编码的消息的大小更轻。因此,消息交换速度更快,即使在 CPU 速度较慢的机器(例如移动设备)中也是如此。


4、gRPC架构


在下面的 gRPC 架构图中,我们有 gRPC 客户端和服务器端。在 gRPC 中,每个客户端服务都包含一个存根(自动生成的文件),类似于包含当前远程过程的接口。


gRPC工作流程:


  • gRPC 客户端将要发送到服务器的参数对存根进行本地过程调用。


  • 客户端存根使用 Protobuf 使用编组过程序列化参数,并将请求转发到本地机器中的本地客户端时间库。


  • 操作系统通过 HTTP/2 协议调用远程服务器机器。


  • 服务器的操作系统接收数据包并调用服务器存根程序,该程序对接收到的参数进行解码并使用 Protobuf 执行相应的程序调用。


  • 服务器存根将编码响应发送回客户端传输层。客户端存根取回结果消息并解包返回的参数,然后执行返回给调用者。


84fd0a66d828452ca6afbae8dd031de5.png


二、准备工作


使用 Go 来编写 gRPC Server 和 Client,让其互相通讯。在此之上会使用到如下库:


下面示例是在 windows环境中安装。


google.golang.org/grpc
google.golang.org/protobuf/cmd/protoc-gen-go
google.golang.org/grpc/cmd/protoc-gen-go-grpc


1.初始化项目go mod init 项目名称模块管理依赖项


go mod init go-grpc-examle


2.安装protoc:


➜ go get -u google.golang.org/grpc


通过--version命令查看是否安装成功:


➜ protoc --version
libprotoc 3.20.1


2.使用以下命令为 Go 安装协议编译器插件:


➜ go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
➜ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2


验证插件是否安装成功:


➜ protoc-gen-go --version
protoc-gen-go.exe v1.28.1
➜ protoc-gen-go-grpc --version
protoc-gen-go-grpc 1.2.0


3.更新你的PATH,以便protoc编译器可以找到插件(你不在gopath下创建的项目,这里自行百度改一下PATH)


三、编写gRPC Client and Server


1、目录结构


go-grpc-example
├── client
│   └──hello_client
│     └── client.go
├── proto
│   └──hello
│     └── hello.proto
├── server
│   └──hello_server
│     └── server.go


2、编写 .proto 文件


syntax = "proto3";
// 定义go生成后的包名
option go_package = "./;hello";
package proto;
// 定义入参
message Request {
  string name =1;
}
// 定义返回
message Response {
  string result = 1;
}
// 定义接口
service UserService {
  rpc Say(Request) returns (Response);
}


3、生成Go代码


# 同时生成hello.pb.go 和 hello_grpc.pb.go
➜ protoc --go-grpc_out=. --go_out=. hello.proto


当前目录下可以看到生成两个文件:


f2da544cb2754ce7b4e2c4e923de1d9c.png


4、编写 Server 服务端代码


编写 gRPC Server 的基础模板,完成一个方法的调用。对 server.go 写入如下内容:


type HelloService struct {
  // 必须嵌入UnimplementedUserServiceServer
  hello.UnimplementedUserServiceServer
}
// 实现SayHi方法
func (h *HelloService) SayHi(ctx context.Context, req *hello.Request) (res *hello.Response, err error) {
  format := time.Now().Format("2006-01-02 15:04:05")
  return &hello.Response{Result: "hi " + req.GetName() + "---" + format}, nil
}
const PORT = "8888"
func main() {
  // 创建grpc服务
  server := grpc.NewServer()
  // 注册服务
  hello.RegisterUserServiceServer(server, &HelloService{})
  // 监听端口
  lis, err := net.Listen("tcp", ":"+PORT)
  if err != nil {
    log.Fatalf("net.Listen err: %v", err)
  }
  server.Serve(lis)
}


5、编写 Client 客户端代码


接下来编写 gRPC Go Client 的基础模板,打开 hello_client/client.go 文件,写入以下内容:


const PORT = "8888"
func main() {
  // 建立链接
  conn, err := grpc.Dial(":"+PORT, grpc.WithInsecure())
  if err != nil {
    log.Fatalf("grpc.Dial err: %v", err)
  }
  // 一定要记得关闭链接
  defer conn.Close()
  // 实例化客户端
  client := hello.NewUserServiceClient(conn)
  // 发起请求
  response, err := client.SayHi(context.Background(), &hello.Request{Name: "lin钟一"})
  if err != nil {
    log.Fatalf("client.SayHi err: %v", err)
  }
  fmt.Printf("resp: %s", response.GetResult())
}


6、启动 & 请求


# 启动服务端
$ go run server.go
API server listening at: 127.0.0.1:50970
# 启动客户端
$ go run client.go 
API server listening at: 127.0.0.1:51040
resp: hi lin钟一---2022-11-01 14:54:01


四、小结


在本文,我们对 gRPC Client/Server 进行了介绍和了解。希望你结合第一章写的rpc请求的方法对文中讲述内容再写一个 Demo 进行深入了解。


下一篇关于gRPC Streaming的内容,gRPC 三种类型的流式。


  • Server-side streaming RPC:服务器端流式 RPC
  • Client-side streaming RPC:客户端流式 RPC
  • Bidirectional streaming RPC:双向流式 RPC
目录
相关文章
|
7月前
|
NoSQL Ubuntu 测试技术
GRPC C++开发环境搭建
GRPC C++开发环境搭建
667 0
|
存储 负载均衡 Cloud Native
gRPC的原理和实践
gRPC的原理和实践
556 1
gRPC的原理和实践
|
2月前
|
网络协议 安全 Go
|
6月前
|
存储 负载均衡 网络协议
gRPC 的原理 介绍带你从头了解gRPC
gRPC 的原理 介绍带你从头了解gRPC
301 2
|
7月前
|
Java Go API
玩转gRPC—Go使用gRPC通信实战
玩转gRPC—Go使用gRPC通信实战
104 1
|
7月前
|
JSON 缓存 Java
ProtoBuf-gRPC实践
gRPC 是一个高性能、开源、通用的 RPC 框架,基于 HTTP/2 设计,使用 Protocol Buffers(ProtoBuf)作为序列化协议。ProtoBuf 允许定义服务接口和消息类型,编译器会生成客户端和服务器端的代码,简化了跨平台的通信。 **gRPC 学习背景** 1. **为什么要学gRPC**:提高网络通信效率,支持多平台、多语言,提供高效序列化和反序列化,以及可靠的安全性和流控。 2. **RPC是什么**:远程过程调用,允许一个程序调用另一个不在同一设备上的程序。 3. **网络库收益分析**:gRPC 提供高效、安全、易用的网
400 0
|
7月前
|
XML Go 开发工具
RPC简介和grpc的使用
RPC简介和grpc的使用
104 0
|
负载均衡
gRPC源码分析(二):从官网文档看gRPC的特性
在第一部分,我们学习了gRPC的基本调用过程,这样我们对全局层面有了一定了解。接下来,我们将结合官方文档,继续深入学习、探索下去。
88 0
|
Go API 开发者
Go语言学习 - RPC篇:gRPC-Gateway示例代码概览
gRPC-Gateway是gRPC生态的一环,用于对HTTP协议的扩展,是一套高性能、高扩展的开源RPC框架。 因此,要掌握gRPC-Gateway,必须要对gRPC有一定的基础,才能明白它的定位与价值。
139 0
|
Java 编译器 API
gRPC 初探与简单使用
gRPC 初探与简单使用
69 0