GRPC介绍

gRPC 是一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。目前提供 C、Java 和 Go 语言版本,分别是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持.

gRPC 基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等特。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。

安装软件包

由于 windows 下安装 GRPC 非常繁琐,推荐在 Linux/MacOS/WSL 下使用 GRPC

使用 Manjaro Linux 可以不用参看本节内容,Manjaro Linux 的 AUR 仓库中自带 GRPC,可以直接从 AUR 中安装

安装 Homebrew

官方文档介绍的安装方式非常繁琐,而且最后编译源代码时还会出错,本人推荐直接使用 Homebrew 来安装

Homebrew 使用 Ruby 环境,没有 Ruby 环境的需要先安装 Ruby。

  • For MacOS:

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  • For Linux

安装,在用户家目录克隆仓库

git clone https://github.com/Homebrew/linuxbrew.git ~/.linuxbrew

克隆到其他目录也可以使用,建议克隆成隐藏目录。

配置环境变量,添加以下内容到用户家目录的.bashrc文件中,如果终端用的是 zsh 那就是 .zshrc

# Until LinuxBrew is fixed, the following is required.
# See: https://github.com/Homebrew/linuxbrew/issues/47
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/local/lib64/pkgconfig:/usr/lib64/pkgconfig:/usr/lib/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib64/pkgconfig:/usr/share/pkgconfig:$PKG_CONFIG_PATH
## Setup linux brew
export LINUXBREWHOME=$HOME/.linuxbrew
export PATH=$LINUXBREWHOME/bin:$PATH
export MANPATH=$LINUXBREWHOME/man:$MANPATH
export PKG_CONFIG_PATH=$LINUXBREWHOME/lib64/pkgconfig:$LINUXBREWHOME/lib/pkgconfig:$PKG_CONFIG_PATH
export LD_LIBRARY_PATH=$LINUXBREWHOME/lib64:$LINUXBREWHOME/lib:$LD_LIBRARY_PATH

如果你的 linuxbrew 克隆在其他地方,请修改 LINUXBREWHOME 参数的值。

使配置立即生效:

# bash
source .bashrc

# zsh
source .zshrc

更改国内源

git -C "$(brew --repo)" remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git

git -C "$(brew --repo homebrew/core)" remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git

git -C "$(brew --repo homebrew/cask)" remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-cask.git

brew update

恢复默认源

git -C "$(brew --repo)" remote set-url origin https://github.com/Homebrew/brew.git

git -C "$(brew --repo homebrew/core)" remote set-url origin https://github.com/Homebrew/homebrew-core.git

git -C "$(brew --repo homebrew/cask)" remote set-url origin https://github.com/Homebrew/homebrew-cask.git

brew update

更改二进制软件包源

在用户家目录下执行:

echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles' >> ~/.bash_profile

source ~/.bash_profile

取消源只需到 .bash_profile 中删除相应的代码即可

安装 GRPC 软件包

brew update

brew install grpc

执行以上命令后,就完成安装 GRPC 扩展及各种编程语言插件,默认安装目录为 /usr/local/bin/,请牢记此目录,后期需要用到。

使用

编写 proto 文件

proto 文件为 GRPC 服务定义文件,用于定义服务端提供哪些服务,客户端如何发送请求,请求需要携带哪些参数,以及服务端如何响应,响应哪些参数等。

proto 示例文件

syntax = "proto3";

option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";

package helloworld;

service Greeter {
    // 一元模式(在一次调用中, 客户端只能向服务器传输一次请求数据, 服务器也只能返回一次响应)
    // unary-unary(In a single call, the client can only send request once, and the server can
    // only respond once.)
    rpc SayHello (HelloRequest) returns (HelloReply);

    // 客户端流模式(在一次调用中, 客户端可以多次向服务器传输数据, 但是服务器只能返回一次响应)
    // stream-unary (In a single call, the client can transfer data to the server several times,
    // but the server can only return a response once.)
    rpc SayHelloClientStreaming (stream HelloRequest) returns (HelloReply);

    // 服务端流模式(在一次调用中, 客户端只能一次向服务器传输数据, 但是服务器可以多次返回响应)
    // unary-stream (In a single call, the client can only transmit data to the server at one time,
    // but the server can return the response many times.)
    rpc SayHelloServerStreaming (HelloRequest) returns (stream HelloReply);

    // 双向流模式 (在一次调用中, 客户端和服务器都可以向对方多次收发数据)
    // stream-stream (In a single call, both client and server can send and receive data
    // to each other multiple times.)
    rpc SayHelloBidirectionalStreaming (stream HelloRequest) returns (stream HelloReply);
}

// The request message containing the user's name.
message HelloRequest {
    string name = 1;
}

// The response message containing the greetings
message HelloReply {
    string message = 1;
}
  • syntax:定义 proto 文件语法版本,示例中使用 proto3 版本

  • option:附加参数,示例中定义了生成 java 基础代码时使用的包名、类名及类前缀等

  • package:生成基础代码文件时使用的文件夹包名,不同的 proto 文件,相同的 package 生成后会放在同一个文件夹中

  • service:定义服务,后面跟服务名称,示例中服务名称为 Greeter,同时该服务包含 4 个接口,各个参数含义如下:

    • rpc:定义服务中的接口,格式为 rpc <接口名称> (<请求消息>) returns (<响应消息>);

    • stream:请求消息和响应消息前加 stream 关键词表示为流模式,接口共支持 4 种模式:

      • 一元模式:在一次调用中, 客户端只能向服务器传输一次请求数据, 服务器也只能返回一次响应

      • 客户端流模式:在一次调用中, 客户端可以多次向服务器传输数据, 但是服务器只能返回一次响应,定义方式为在请求消息前加 stream 参数

      • 服务端流模式:在一次调用中, 客户端只能一次向服务器传输数据, 但是服务器可以多次返回响应,定义方式为在响应消息前加 stream 参数

      • 双向流模式:在一次调用中, 客户端和服务器都可以向对方多次收发数据,定义方式为在请求消息和响应消息前加 stream 参数

    • message:定义请求消息和响应消息

更多proto文件说明可参看 protobuf语法指南 一文

生成基础代码

生成 Python 基础代码

先安装 GRPC 的 python 扩展包

python -m pip install grpcio
python -m pip install grpcio-tools

推荐将其安装在项目的虚拟环境中

执行以下命令从 proto 文件生成基础代码

python -m grpc_tools.protoc -I ../../protos \
    --python_out=. \
    --grpc_python_out=. \
    ../../protos/helloworld.proto
  • -I 指定proto文件所在目录

  • --python_out--grpc_python_out 指定最终生成的基础代码存放路径

  • 最后一个参数指定具体的 proto 文件,该文件必须在 -I 参数指定的路径中

执行后会生成 xxx_pb2.pyxxx_pb2_grpc.py 两个文件,将两个文件复制到自己项目中即可。

生成PHP基础代码

根据本教程使用 Homebrew 安装了 GRPC 软件包后就可以使用以下命令生成代码文件:

protoc --proto_path=examples/protos \
  --php_out=examples/php \
  --grpc_out=examples/php \
  --plugin=protoc-gen-grpc=bins/opt/grpc_php_plugin \
  ./examples/protos/helloworld.proto
  • --proto_path 指定proto文件路径

  • --php_out 指定php基础代码生成存放路径

  • --grpc_out 指定grpc基础代码存放路径

  • --plugin 指定使用的 grpc 语言插件,使用本教程安装的插件存放于 /usr/local/bin/

  • 最后指定需要生成代码的 proto 文件,该文件必须位于 --proto_path 路径中

现在 grpc 的基础文件就有了,后续我会更新具体在语言项目中如何使用 grpc。