最简单的 gRPC 教程— 1 初识 gRPC

简介: gRPC 是 Google 开源的一个高性能的 RPC(Remote Procedure Call) 框架

LDJC1~2DZ{IX~FVJZ[PJ2HB.png

gRPC 是 Google 开源的一个高性能的 RPC(Remote Procedure Call) 框架,它具有如下的优点:

  • 提供高效的进程间通信。gRPC 没有使用 XML 或者 JSON 这种文本格式,而是采用了基于 protocol buffers 的二进制协议;同时,gRPC 采用了 HTTP/2 做为通信协议,从而能够快速的处理进程间通信。
  • 简单且良好的服务接口和模式。gRPC 为程序开发提供了一种契约优先的方式,必须首先定义服务接口,才能处理实现细节。
  • 支持多语言。gRPC 是语言中立的,我们可以选择任意一种编程语言,都能够与 gRPC 客户端或者服务端进行交互。
  • 成熟并且已被广泛使用。通过在 Google 的大量实战测试,gRPC 已经发展成熟。

下面通过一个简单的 demo 来初步了解 gRPC 的使用。

我们构建一个商品服务,命名为 ProductInfo,客户端和服务端的交互模式如下:

FGS{9{MYZ3Q8)Y1LV6C)8VO.png

首先我们需要定义 protobuf:

syntax = "proto3";
package product;
service ProductInfo {
  //添加商品
  rpc addProduct(Product) returns (ProductId);
  //获取商品
  rpc getProduct(ProductId) returns (Product);
}
message Product {
  string id = 1;
  string name = 2;
  string description = 3;
}
message ProductId {
  string value = 1;
}

我们定义了一个 ProductInfo 服务,其中有两个方法,分别是添加商品和获取商品,然后在 proto 文件所在的目录下执行命令 protoc --go_out=plugins=grpc:../product ProductInfo.proto

如果没有安装 protoc,执行命令 go get -u github.com/golang/protobuf/protoc-gen-go 进行安装。虽然 gRPC 支持多种语言,但是为了统一,我文章中的代码都使用 Go。

执行完之后,在 proto 文件同级目录下会出现一个 ProductInfo.pb.go 文件:

NX[0Z~6WC1]IH3ET){45@9X.png

然后在 product 文件夹下新建一个 server 文件夹,然后新建一个 main.go 文件,首先在文件中实现 ProductInfo 服务的两个方法的业务逻辑:

package main
import (
   "context"
   "github.com/gofrs/uuid"
   "google.golang.org/grpc/codes"
   "google.golang.org/grpc/status"
   "grpc-demo/product"
)
type server struct {
   productMap map[string]*product.Product
}
//添加商品
func (s *server) AddProduct(ctx context.Context, req *product.Product) (resp *product.ProductId, err error) {
   resp = &product.ProductId{}
   out, err := uuid.NewV4()
   if err != nil {
      return resp, status.Errorf(codes.Internal, "err while generate the uuid ", err)
   }
   req.Id = out.String()
   if s.productMap == nil {
      s.productMap = make(map[string]*product.Product) 
   }
   s.productMap[req.Id] = req
   resp.Value = req.Id
   return
}
//获取商品
func (s *server) GetProduct(ctx context.Context, req *product.ProductId) (resp *product.Product, err error) {
   if s.productMap == nil {
      s.productMap = make(map[string]*product.Product)
   }
   resp = s.productMap[req.Value]
   return
}
然后继续在 main.go 文件中添加一个 main 方法,建立一个 gRPC 服务器:
func main() {
   listener, err := net.Listen("tcp", port)
   if err != nil {
      log.Println("net listen err ", err)
      return
   }
   s := grpc.NewServer()
   product.RegisterProductInfoServer(s, &server{})
   log.Println("start gRPC listen on port " + port)
   if err := s.Serve(listener); err != nil {
      log.Println("failed to serve...", err)
      return
   }
}

服务端的逻辑就到这里了,接下来再写一下客户端的逻辑,建立一个 client 文件夹,然后新建一个 main.go 文件,内容如下:

package main
import (
   "context"
   "google.golang.org/grpc"
   "grpc-demo/product"
   "log"
)
const (
   address = "localhost:50051"
)
func main() {
   conn, err := grpc.Dial(address, grpc.WithInsecure())
   if err != nil {
      log.Println("did not connect.", err)
      return
   }
   defer conn.Close()
   client := product.NewProductInfoClient(conn)
   ctx := context.Background()
   id := AddProduct(ctx, client)
   GetProduct(ctx, client, id)
}
// 添加一个测试的商品
func AddProduct(ctx context.Context, client product.ProductInfoClient) (id string) {
   aMac := &product.Product{Name: "Mac Book Pro 2019", Description: "From Apple Inc."}
   productId, err := client.AddProduct(ctx, aMac)
   if err != nil {
      log.Println("add product fail.", err)
      return
   }
   log.Println("add product success, id = ", productId.Value)
   return productId.Value
}
// 获取一个商品
func GetProduct(ctx context.Context, client product.ProductInfoClient, id string) {
   p, err := client.GetProduct(ctx, &product.ProductId{Value: id})
   if err != nil {
      log.Println("get product err.", err)
      return
   }
   log.Printf("get prodcut success : %+v\n", p)
}

然后先启动 server/main.go ,再启动 client/main.go,这样一次服务端和客户端之间的连接便完成了,可以看到运行的结果输出了:

O2G1F{3{SQGIS5GX)X}LS35.png

当然你也可以在服务端的方法中,加上一些日志来验证一下。

最后,这个小的 demo 的目录结构就是这样的:

@Q]~SVUG{2]E0AT7SN1{%KL.png

项目的代码在我的GitHub 上:https://github.com/roseduan/grpc-demo

相关文章
|
17小时前
|
JSON 缓存 Java
ProtoBuf-gRPC实践
gRPC 是一个高性能、开源、通用的 RPC 框架,基于 HTTP/2 设计,使用 Protocol Buffers(ProtoBuf)作为序列化协议。ProtoBuf 允许定义服务接口和消息类型,编译器会生成客户端和服务器端的代码,简化了跨平台的通信。 **gRPC 学习背景** 1. **为什么要学gRPC**:提高网络通信效率,支持多平台、多语言,提供高效序列化和反序列化,以及可靠的安全性和流控。 2. **RPC是什么**:远程过程调用,允许一个程序调用另一个不在同一设备上的程序。 3. **网络库收益分析**:gRPC 提供高效、安全、易用的网
104 0
|
17小时前
|
Java Go API
玩转gRPC—Go使用gRPC通信实战
玩转gRPC—Go使用gRPC通信实战
34 1
|
17小时前
|
Dubbo Java 应用服务中间件
grpc&rpc
grpc&rpc
|
17小时前
|
负载均衡 监控 安全
介绍grpc
gRPC(gRPC Remote Procedure Call)是一种高性能、开源的远程过程调用(RPC)框架,最初由Google开发并开源。它基于HTTP/2协议传输,使用Protocol Buffers(ProtoBuf)作为默认的序列化机制,支持多种编程语言,并提供了强大的功能和特性。
|
17小时前
|
XML Go 开发工具
RPC简介和grpc的使用
RPC简介和grpc的使用
61 0
|
6月前
|
XML JSON 网络协议
gRPC介绍
gRPC介绍
|
7月前
|
负载均衡
gRPC源码分析(二):从官网文档看gRPC的特性
在第一部分,我们学习了gRPC的基本调用过程,这样我们对全局层面有了一定了解。接下来,我们将结合官方文档,继续深入学习、探索下去。
28 0
|
7月前
|
JSON Go 网络架构
《gRPC vs REST:何时选择哪一个》
《gRPC vs REST:何时选择哪一个》
54 0
|
XML JSON 网络协议
gRPC笔记与相关问题
gRPC笔记与相关问题
|
Cloud Native 物联网 编译器
gRPC(三)基础:gRPC快速入门
Protobuf 是 Google 的序列化/反序列化协议,可以轻松定义服务和自动生成客户端库。gRPC 使用此协议作为其接口定义语言 (IDL) 和序列化工具集。
303 0
gRPC(三)基础:gRPC快速入门