A4. gRPC的简单实践

Posted artikell

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了A4. gRPC的简单实践相关的知识,希望对你有一定的参考价值。

a. 前言

公司内部各个服务调用会使用各式各样的rpc协议,而gRPC逐步的开始成为协议的热门,本期来了解一下gRPC的发展,并进行相关的实验。


b. gRPC的历史

众所周知:gRPC 是一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。

这是所有介绍里面都会说的一句话,里面有3个核心点:高性能、面向移动、HTTP/2。所以问题在于gRPC是如何实现这3个特点。

相对官方的文档有2个:

  1. 官网:https://www.grpc.io/docs/what-is-grpc/

  2. 开源中国组织翻译的《gRPC 官方文档中文版》:http://doc.oschina.net/grpc


b.1 gRPC的特性

从相关文章中,能摘录出一下3个特性。

基于HTTP/2

HTTP/2 提供了连接多路复用、双向流、服务器推送、请求优先级、首部压缩等机制。可以节省带宽、降低TCP链接次数、节省CPU,帮助移动设备延长电池寿命等。gRPC 的协议设计上使用了HTTP2 现有的语义,请求和响应的数据使用HTTP Body 发送,其他的控制信息则用Header 表示。

IDL使用ProtoBuf

gRPC使用ProtoBuf来定义服务,ProtoBuf是由Google开发的一种数据序列化协议(类似于XML、JSON、hessian)。ProtoBuf能够将数据进行序列化,并广泛应用在数据存储、通信协议等方面。压缩和传输效率高,语法简单,表达力强。

多语言支持(C, C++, Python, php, Nodejs, C#, Objective-C、Golang、Java)

gRPC支持多种语言,并能够基于语言自动生成客户端和服务端功能库。目前已提供了C版本grpc、Java版本grpc-java 和 Go版本grpc-go,其它语言的版本正在积极开发中,其中,grpc支持C、C++、Node.js、Python、Ruby、Objective-C、PHP和C#等语言,grpc-java已经支持android开发。


基于上述几个特性,gRPC已经应用在Google的云服务和对外提供的API中,其主要应用场景如下:

  • 低延迟、高扩展性、分布式的系统

  • 同云服务器进行通信的移动应用客户端

  • 设计语言独立、高效、精确的新协议

  • 便于各方面扩展的分层设计,如认证、负载均衡、日志记录、监控等

也可以看出gRPC和thrift之间的区别:

[tcp/udp [http2     [PrototBuf  [gRPC Data   ]]]]
[tcp     [TTransport[TProtocal [thrift Data ]]]]

在数据和TCP链接中,分别把传输方式和编码协议给替换。

既然如此,那2者直接的核心差异都有哪些?


c. gRPC实践

首先,需要搭建gRPC的基本环境。当然存在2种方法:apt包管理安装、原生安装。这就不过多赘述。直接进入proto文件的编写。

proto文件就类比thrift文件的IDL文件,英文全称是:交互式数据语言Interactive Data Language,下面是一个简单的实例:

syntax = "proto3";  //语法声明

package protodemo; //包名

// DemoHello 微服务
service DemoHello {
// Sends a message
    rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// HelloRequest 请求数据格式
message HelloRequest {
    string name = 1;
}

// HelloReply 响应数据格式
message HelloReply {
    string message = 1;
}

这简单的实例中存在几个关键点:

  1. syntax,当前版本协议

  2. service,定义一个服务

  3. rpc,定义一个rpc接口

  4. message,定义一个结构体类型

至此,我们就拥有了一个简单的proto文件,接下来就可以使用下面的命令来生成一个golang的代码。

protoc --go_out=plugins=grpc:. hello.proto

这样就可以在当前目录下面生成一个hello.pb.go的文件。

既然是rpc,那肯定是存在client和server2个端,于是我们需要分别写下2端的代码逻辑。

客户端代码如下:

/**
client/main.go 文件
> mkdir client
> cd client
> go mod init github.com/demo/client
> mkdir protodemo
> cp ../hello.proto protodemo
**/
package main

import (
  "context"
  "log"
  "os"
  "time"

  "google.golang.org/grpc"
  pb "github.com/demo/client/protodemo"
)

const (
  address     = "localhost:11423"
  defaultName = "world"
)

func main() {
  conn, err := grpc.Dial(address, grpc.WithInsecure())
  if err != nil {
      log.Fatalf("did not connect: %v", err)
  }
  defer conn.Close()
  c := pb.NewDemoHelloClient(conn)

  name := defaultName
  if len(os.Args) > 1 {
      name = os.Args[1]
  }

  ctx, cancel := context.WithTimeout(context.Background(), time.Second)
  defer cancel()
  r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name})
  if err != nil {
      log.Fatalf("could not greet: %v", err)
  }
  log.Printf("Hello world: %s", r.Message)
}

服务端代码如下:

/**
server/main.go 文件
> mkdir server
> cd server
> go mod init github.com/demo/server
> mkdir protodemo
> cp ../hello.proto protodemo
**/
package main

import (
  "context"
  "log"
  "net"

  "time"
  "google.golang.org/grpc"
  pb "github.com/demo/server/protodemo"
  "google.golang.org/grpc/reflection"
)

const (
  port = ":11423"
)


type server struct{} //服务对象

// SayHello 实现服务的接口 在proto中定义的所有服务都是接口
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
      t := time.Now()
      return &pb.HelloReply{Message: "Hello " + in.Name + "\n Now Time is: " + t.Format("20060102150405")}, nil
}

func main() {
  lis, err := net.Listen("tcp", port)
  if err != nil {
      log.Fatalf("failed to listen: %v", err)
  }
  s := grpc.NewServer() //起一个服务
  pb.RegisterDemoHelloServer(s, &server{})
  // 注册反射服务 这个服务是CLI使用的 跟服务本身没有关系
  reflection.Register(s)
  if err := s.Serve(lis); err != nil {
      log.Fatalf("failed to serve: %v", err)
  }
}

其中当然是直接使用最新的gomod来管理。

在启动server端后,我们就可以调用client来进行通信。

至此是gRPC的基础实践,但在实践过程中,会存在多种疑问,如下:

  1. thrift和pb的优缺点

  2. pb的版本兼容

  3. gRPC的性能情况

  4. http2的高效

  5. thrift和gRPC的使用场景

  6. pb在移动端的使用

  7. ... ...

这些疑问在后续将逐步了解并整理。

z. 相关链接

https://solicomo.com/network-dev/protobuf-proto3-vs-proto2.html

http://hengyunabc.github.io/thinking-about-grpc-http2/

https://zhuanlan.zhihu.com/p/148139089


以上是关于A4. gRPC的简单实践的主要内容,如果未能解决你的问题,请参考以下文章

RPC基础系列3gRPC简单示例

Golang gRPC 实践

gRPC认证的多种方式实践(排版整理)

SpringBoot集成gRPC微服务工程搭建实践

gRPC三种Java客户端性能测试实践

花椒服务端 gRPC 开发实践