第六届字节跳动青训营——深入浅出RPC框架 | 青训营

103 阅读3分钟

内容概述

RPCRemote Procedure Call的简称,中文叫远程过程调用。简单的说,就是调用远程方法和调用本地方法一样。那么grpc就是由 google开发的一个高性能、通用的开源RPC框架

主要内容

grpc安装

安装其实很简单,以windows操作系统为例,只需要安装protoc转换工具。 安装网址如下:github.com/protocolbuf… 安装完成之后需要将protoc的bin目录添加至环境变量中,此外还需要将protoc-gen-go.exe的目录添加至环境变量中。添加完毕之后,最好重启一下电脑。需要安装的依赖如下:

go get github.com/golang/protobuf/proto

go get google.golang.org/grpc

go install github.com/golang/protobuf/protoc-gen-go

proto文件

使用RPC框架需要编写proto文件,我们先介绍一下proto文件,proto文件只是定义接口方法,以下为一个样例。service 对应的就是go里面的接口,可以作为服务端,客户端。rpc 对应的就是结构体中的方法。message对应的也是结构体。

syntax = "proto3"; // 指定proto版本
package hello_grpc;     // 指定默认包名

// 指定golang包名
option go_package = "/hello_grpc";

//定义rpc服务
service HelloService {
  // 定义函数
  rpc SayHello (HelloRequest) returns (HelloResponse) {}
}

// HelloRequest 请求内容
message HelloRequest {
  string name = 1;  // 消息号
  string message = 2;
}

// HelloResponse 响应内容
message HelloResponse{
  string name = 1;
  string message = 2;
}

proto使用过程

在grpc_proto目录下执行protoc -I . --go_out=plugins=grpc:. .\hello.proto

或者在根目录下执行protoc -I . --go_out=plugins=grpc:.\grpc_proto .\grpc_proto\hello.proto 在服务端:

  1. 编写一个结构体,名字叫什么不重要
  2. 重要的是得实现protobuf中的所有方法
  3. 监听端口
  4. 注册服务
package main

import (
  "context"
  "fmt"
  "google.golang.org/grpc"
  "google.golang.org/grpc/grpclog"
  "grpc_study/grpc_proto/hello_grpc"
  "net"
)

type HelloServer1 struct {
}

func (HelloServer1) SayHello(ctx context.Context, request *hello_grpc.HelloRequest) (pd *hello_grpc.HelloResponse, err error) {
  fmt.Println("入参:", request.Name, request.Message)
  pd = new(hello_grpc.HelloResponse)
  pd.Name = "你好"
  pd.Message = "ok"
  return
}

func main() {
  // 监听端口
  listen, err := net.Listen("tcp", ":8080")
  if err != nil {
    grpclog.Fatalf("Failed to listen: %v", err)
  }
  
  // 创建一个gRPC服务器实例。
  s := grpc.NewServer()
  server := HelloServer1{}
  // 将server结构体注册为gRPC服务。
  hello_grpc.RegisterHelloServiceServer(s, &server)
  fmt.Println("grpc server running :8080")
  // 开始处理客户端请求。
  err = s.Serve(listen)
}

在客户端:

  1. 建立连接
  2. 调用方法
package main

import (
  "context"
  "fmt"
  "google.golang.org/grpc"
  "google.golang.org/grpc/credentials/insecure"
  "grpc_study/grpc_proto/hello_grpc"
  "log"
)

func main() {
  addr := ":8080"
  // 使用 grpc.Dial 创建一个到指定地址的 gRPC 连接。
  // 此处使用不安全的证书来实现 SSL/TLS 连接
  conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
  if err != nil {
    log.Fatalf(fmt.Sprintf("grpc connect addr [%s] 连接失败 %s", addr, err))
  }
  defer conn.Close()
  // 初始化客户端
  client := hello_grpc.NewHelloServiceClient(conn)
  result, err := client.SayHello(context.Background(), &hello_grpc.HelloRequest{
    Name:    "zhouzhou",
    Message: "ok",
  })
  fmt.Println(result, err)
}

内容总结

总的来说,gRPC是一个高性能,开源和通用的RPC框架,基于Protobuf序列化协议开发。面向服务端和客户端。定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个接口。并运行一个gRPC服务器来处理客户端调用。在客户端拥有一个存根能够向服务端一样的方法。

主要优势:

与采用文本格式的json相比,采用二进制格式的protobuf在速度上可以达到前者的5倍。

提供代码生成,无需编写客户端代码,可在具有许多服务和应用程序中节省大量开发时间。

gRPC服务支持所有流组合。

gRPC规范是规定有关gPRC服务必须遵循的格式。gRPC消除了争论并节省了开发人员的时间,因为gRPC在各个平台上和实现之间是一致的。

适用场景:

gRPC设计为低延迟和高吞吐量通信,非常适用效率至关重要的轻型微服务。

gRPC可以实时推送消息而无需轮询,因此适用点对点实时通信。

支持所有流行开发语言,因此适用多语言混合开发环境。

使用Protobuf(一种轻量级消息格式)序列化gRPC消息,gRPC消息始终小于等效的JSON消息,因此适用网络受限环境。