一、gRPC是什么?

gRPC,其实就是RPC框架的一种,前面带了一个g,代表是RPC中的大哥,龙头老大的意思,另外g也有global的意思,意思是全球化比较fashion,是一个高性能、开源和通用的 RPC 框架,面向服务端和移动端,基于 HTTP/2 设计。

RPC框架是什么?

RPC 框架说白了就是让你可以像调用本地方法一样调用远程服务提供的方法,而不需要关心底层的通信细节。简单地说就让远程服务调用更加简单、透明。
RPC包含了客户端(Client)和服务端(Server)

常见的RPC框架有

  1. gRPC。谷歌出品
  2. Thrift。Apache出品
  3. Dubbo。阿里出品,也是一个微服务框架

gRPC的特性

看官方文档的介绍,有以下4点特性:

  1. 使用Protocal Buffers这个强大的结构数据序列化工具
  2. grpc可以跨语言使用
  3. 安装简单,扩展方便(用该框架每秒可达到百万个RPC)
  4. 基于HTTP2协议

gRPC使用流程

gprc的使用流程一般是这样的:

  1. 定义标准的proto文件
  2. 生成标准代码
  3. 服务端使用生成的代码提供服务
  4. 客户端使用生成的代码调用服务

二、Protocol Buffers是什么?

谷歌开源的一种结构数据序列化的工具,比方说JSON、XML也是结构数据序列化的工具,不同的是,

  1. Protocol Buffers序列化后的数据是不可读的,因为是二进制流
  2. 使用Protocol Buffer需要事先定义数据的格式(.proto 协议文件),还原一个序列化之后的数据需要使用到这个数据格式
  3. Protocol Buffer 比 XML、JSON快很多,因为是基于二进制流,比字符串更省带宽,传输速度快
    Protocol Buffer语法:查看官方文档

下面演示根据需求开发项目,建议自己运行一下,加深印象

三、需求:开发健身房服务

定义了一个健身房(Gym),提供一个叫健身(Bodybuilding)的远程方法
使用该服务,需要指定人(Person),人有名字(name)和训练动作(actions)两个属性。

对应的协议文件gym.proto文件如下

syntax = "proto3";
//命名空间
package lightweight;//健身房
service Gym {rpc BodyBuilding (Person) returns (Reply) {}
}
//谁在健身
message Person {string name = 1;repeated string actions = 2;
}//结果
message Reply {int32 code = 1;string msg = 2;
}

四、最佳实践

下面以Golang、Python、PHP介绍该grpc的使用,代码已经上传到了chenqionghe/grpc-demo
最终目录结构如下图

Golang

1. 安装protoc

地址:protobuf/releases
我是mac,用的是这个地址:protoc-3.11.4-osx-x86_64.zip
解压后放到了可以访问的bin即可

2. 安装protoc-gen-go

protoc依赖该工具生成代码

go get -u github.com/golang/protobuf/protoc-gen-go

gogoprotobuf的protoc-gen-gofast插件生成的文件更复杂,性能也更高,安装如下
go get github.com/gogo/protobuf/protoc-gen-gofast

3. 安装grpc包

这是要代码里需要使用的,go get直接安装不了,手动克隆

git clone https://github.com/grpc/grpc-go.git $GOPATH/src/google.golang.org/grpc
git clone https://github.com/golang/net.git $GOPATH/src/golang.org/x/net
git clone https://github.com/golang/text.git $GOPATH/src/golang.org/x/text
git clone https://github.com/google/go-genproto.git $GOPATH/src/google.golang.org/genproto
cd $GOPATH/src/
go install google.golang.org/grpc

4. 生成代码

#!/usr/bin/env bashprotoDir="../protos"
outDir="../languages/golang/gym"
protoc -I ${protoDir}/ ${protoDir}/*proto --go_out=plugins=grpc:${outDir}

protoc工具参数解释:

  • -I: 指定import路径,可以指定多个-I参数,编译时按顺序查找,不指定默认当前目录
  • -go_out:指定og语言的访问类
  • plugins:指定依赖的插件
使用gofast将go_out=plugins=grpc:${outDir}改为gofast_out=plugins=grpc:${outDir}

执行,然后我们会看到在golang目录生成了该代码

5. 定义服务端

package mainimport ("app/lightweight""context""fmt""google.golang.org/grpc""log""net"
)const (port = ":50051"
)// server继承自动生成的服务类
type server struct {lightweight.UnimplementedGymServer
}// 服务端必须实现了相应的接口BodyBuilding
func (s *server) BodyBuilding(ctx context.Context, in *lightweight.Person) (*lightweight.Reply, error) {fmt.Printf("%s正在健身, 动作: %s\n", in.Name, in.Actions)return &lightweight.Reply{Code: 0, Msg: "ok",}, nil
}
func main() {lis, err := net.Listen("tcp", port)if err != nil {log.Fatalf("failed to listen: %v", err)}s := grpc.NewServer()lightweight.RegisterGymServer(s, &server{})if err := s.Serve(lis); err != nil {log.Fatalf("failed to serve: %v", err)}
}

6. 定义客户端

package mainimport ("app/lightweight""context""fmt""google.golang.org/grpc""log""time"
)const (address = "localhost:50051"
)func main() {// Set up a connection to the server.conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock())if err != nil {log.Fatalf("did not connect: %v", err)}defer conn.Close()c := lightweight.NewGymClient(conn)ctx, cancel := context.WithTimeout(context.Background(), time.Second)defer cancel()r, err := c.BodyBuilding(ctx, &lightweight.Person{Name: "chenqionghe",Actions: []string{"深蹲", "卧推", "硬拉"},})if err != nil {log.Fatalf("error: %v", err)}fmt.Printf("code: %d, msg: %s", r.Code, r.Msg)
}

7. 运行代码

golang目录结果是现在是这样的

.
├── client.go
├── go.mod
├── go.sum
├── lightweight
│ └── gym.pb.go
└── server.go

运行服务端和客户端,效果如下

可以看到,chenqionghe去健身成功

Python

1. 安装grpc包

pip install grpcio

2. 安装protobuf

pip install protobuf

3. 安装grpc的protobuf编译工具

包含了protoc编译器和生成代码的插件

pip install grpcio-tools

4. 生成代码

#!/usr/bin/env bashprotoDir="../protos"
outDir="../languages/python/gym/"python3 -m grpc_tools.protoc -I ${protoDir}/ --python_out=${outDir} --grpc_python_out=${outDir} ${protoDir}/*proto

5. 定义服务端

from concurrent import futures
import logging
import grpc# 支持新的包
import sys
sys.path.append("lightweight")
import lightweight.gym_pb2_grpc as gym_pb2_grpc
import lightweight.gym_pb2 as gym_pb2class Gym(gym_pb2_grpc.GymServicer):def BodyBuilding(self, request, context):print(f"{request.name}在健身, 动作: {list(request.actions)}")return gym_pb2.Reply(code=0, msg='ok')def serve():server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))gym_pb2_grpc.add_GymServicer_to_server(Gym(), server)server.add_insecure_port('[::]:50051')server.start()server.wait_for_termination()if __name__ == '__main__':logging.basicConfig()serve()

6. 定义客户端

from __future__ import print_function
import logging
import grpc# 支持导入新的包
import sys
sys.path.append("lightweight")
import lightweight.gym_pb2_grpc as gym_pb2_grpc
import lightweight.gym_pb2 as gym_pb2def run():with grpc.insecure_channel('localhost:50051') as channel:stub = gym_pb2_grpc.GymStub(channel)response = stub.BodyBuilding(gym_pb2.Person(name='chenqionghe', actions=['深蹲', '卧推', '硬拉']))print(f'code: {response.code}, msg:{response.msg}')if __name__ == '__main__':logging.basicConfig()run()

7. 运行代码

目录结构如下,分别运行

├── client.py
├── lightweight
│ ├── gym_pb2.py
│ └── gym_pb2_grpc.py
└── server.py


可以看到,chenqionghe去健身成功

PHP

1. 安装protoc

地址:protobuf/releases
我是mac,用的是这个地址:protoc-3.11.4-osx-x86_64.zip
解压后放到了可以访问的bin即可

2. 安装grpc扩展

方式一:pecl安装

pecl install grpc

将扩展加入到php.ini

extension=grpc.so

3. 安装protobuf扩展

pecl install protobuf

将扩展加入到php.ini

extension=protobuf.so

4. 安装生成代码的插件grpc_php_plugin

该插件用来生成PHP的gRPC代码

git clone -b v1.27.0 https://github.com/grpc/grpc
cd grpc && git submodule update --init && make grpc_php_plugin

注意:这个过程耗时比较久,请做好心理准备(可以在.gitmodules文件中看到依赖的仓库比较多)

画风是这样的

如果grpc_php_plugin安装不上,mac系统可以直接copy我已经编译好的grpc_php_plugin

安装完成画风

最终会在bins/opt下生成grpc_php_plugin文件,我们把它移动到/usr/local/bin下

5. 生成代码

#!/usr/bin/env bashprotoDir="../protos"
outDir="../languages/php/lightweight"
protoc -I ${protoDir}/ ${protoDir}/*proto --go_out=plugins=grpc:${outDir}protoc --proto_path=${protoDir} \--php_out=${outDir} \--grpc_out=${outDir} \--plugin=protoc-gen-grpc=/usr/local/bin/grpc_php_plugin \${protoDir}/*.proto

生成代码如下

6. 定义客户端

1.创建composer.json文件并执行

{"name": "gym","require": {"grpc/grpc": "^v1.3.0","google/protobuf": "^v3.3.0"},"autoload": {"psr-4": {"GPBMetadata\\": "lightweight/GPBMetadata/","Lightweight\\": "lightweight/Lightweight/"}}
}

执行composer install
2.创建客户端文件client.php

<?php
/*** 客户端使用示例* @author chenqionghe*/require dirname(__FILE__) . '/vendor/autoload.php';//初始化要去的健身房
$client = new \Lightweight\GymClient('127.0.0.1:50051', ['credentials' => Grpc\ChannelCredentials::createInsecure(),
]);
//带上自己的卡和运动计划
$request = new \Lightweight\Person();
$request->setName("chenqionghe");
$request->setActions(['深蹲', '卧推', '硬拉']);
//去健身房健身
list($response, $status) = $client->BodyBuilding($request)->wait();
echo sprintf("code: %s, msg: %s \n", $response->getCode(), $response->getMsg());

注意:php不支持grpc的服务端,建议服务端起一个上面的golang或者python中的server
这里我用的是golang的

7. 运行代码


可以看到,chenqionghe去健身成功,yes,就是这么easy!

五、如何调试gRPC

我们都知道rest api是可用curl和postman这样的工具来调试的,grpc也有类似的工具,对应的分别是grpcurl和grpcui

grpcurl-命令行工具

类似curl,可以直接用来发送请求调用远程的grpc服务,官方地址请看grpcurl

安装

brew直接安装

brew install grpcurl

也可以使用go get安装

go get github.com/fullstorydev/grpcurl
go install github.com/fullstorydev/grpcurl/cmd/grpcurl

使用

注意grpcl是基于反射,需要在启动服务前添加这样一行代码

 reflection.Register(s)

1.查询服务列表

grpcurl -plaintext 127.0.0.1:50051 list

2.查询服务提供的方法

grpcurl -plaintext 127.0.0.1:50051 list lightweight.Gym

3.查看更详细的描述

grpcurl -plaintext 127.0.0.1:50051 describe lightweight.Gym

4.获取类型信息

grpcurl -plaintext 127.0.0.1:50051 describe lightweight.Person

5.调用服务方法

grpcurl -plaintext -d '{"name":"chenqionghe","actions":["深蹲","卧推","硬拉"]}' 127.0.0.1:50051 lightweight.Gym/BodyBuilding

grpcui-界面工具

简单的说,就是gRPC中的postman,能带你飞起来那种,官方地址grpcui

安装

go get github.com/fullstorydev/grpcui
go install github.com/fullstorydev/grpcui/cmd/grpcui

使用

运行web界面,指定grpc的地址

grpcui -plaintext localhost:50051

提示Web UI的地址为http://127.0.0.1:50791
访问出来以下界面

直接把所有服务和方法都列出来了,真的是相当人性化
我们来使用一下,传递参数

返回结果如下

到服务端查看,已经正常的接收到请求

OK,到这里,分别演示了Golang、Python、PHP使用gRPC的例子,以及gRPC调试工具,就是这么简单粗暴!light weight baby !

gRPC详细入门教程,Golang/Python/PHP多语言讲解相关推荐

  1. openCV超详细入门教程(python版)

    涉及内容: 背景提取 颜色过滤 边缘检测 用于对象识别的特征匹配 一般对象识别 你将需要两个主要的库,第三个可选:python-OpenCV,Numpy 和 Matplotlib. 一.加载图片 首先 ...

  2. Swig超详细入门教程(Java调用C/C++, CMake)——更新于2021.12

    目录 相关教程 环境配置 0基础上手例子(C/C++) 使用CMake的例子(C语言) 使用CMake的例子(C++) 本文主要是手把手教萌新们如何用官方用例构建(有许多本人亲身踩坑血泪史) 相关教程 ...

  3. TypeScript超详细入门教程(上)

    TypeScript超详细入门教程(上) 01 开篇词:Hello~TypeScript 01 开篇词:Hello~TypeScript 更新时间:2019-10-30 13:49:46 既然我已经踏 ...

  4. 543、RabbitMQ详细入门教程系列 -【Confirm与Mandatory】 2022.09.05

    目录 一.前言概述 二.SpringAMQP配置Confirm 2.1 Connection设置 2.2 template设置 2.3 Confirm实现 三.SpringAMQP配置ManDator ...

  5. 544、RabbitMQ详细入门教程系列 -【手动消费确认】 2022.09.05

    目录 一.前言概述 二.配置实现 2.1 XML配置 2.2 MessageListener实现 三.消息预取 四.并发消费 五.参考链接 一.前言概述 RabbitMQ(四) --消费者Consum ...

  6. 【endnote详细入门教程】

    Endnote详细入门教程 一.下载引用,导入文献 二.在word中插入引用 三.文献分类.注释 四.预览.引用格式 一.下载引用,导入文献 1.可以从不同的文献下载网站进行导入: (1)web of ...

  7. Apollo Control——超详细入门教程(二):连续状态空间方程离散化与离散LQR公式推导

    专栏文章列表 Apollo Control--超详细入门教程(一):基于道路误差的车辆动力学模型 Apollo Control--超详细入门教程(二):连续状态空间方程离散化与离散LQR公式推导 Ap ...

  8. python画图颜色表示大小变化_python画图(线条颜色、大小、类型:点、虚线等)(图文详细入门教程四)...

    初衷 本人由于平常写论文需要输出一些结果图,但是苦于在网上搜python画图时,详细的教程非常多,但是就是找不到能马上解决自己问题那一行代码,所以打算写一些适合需求简单的朋友应急用的教程,应急就必须方 ...

  9. python画图marker显示_python画图(标记、marker、设置标记大小、marker符号大全)(图文详细入门教程五)...

    初衷 本人由于平常写论文需要输出一些结果图,但是苦于在网上搜python画图时,详细的教程非常多,但是就是找不到能马上解决自己问题那一行代码,所以打算写一些适合需求简单的朋友应急用的教程,应急就必须方 ...

最新文章

  1. 人工智能改变生活的10种方式
  2. Flask-session
  3. enumerate()使用
  4. 排序算法——随机快速排序
  5. Jmeter安装设置
  6. IDEA Maven 聚合项目(多模块)搭建--最精简
  7. 解决自己电脑VMware打开虚拟机黑屏问题
  8. vue点击按钮跳转页面
  9. 《念奴娇·赤壁怀古》古词鉴赏
  10. Windows10 LSTC 2021输入法无法使用的问题
  11. echarts——横向柱状图
  12. 傲游浏览器 页面广告过滤 自定义 过滤规则 及使用方法 不定时更新
  13. 华为鸿蒙2.0系统电脑安装步骤,华为鸿蒙系统2.0怎么安装,鸿蒙系统2.0安装教程...
  14. 猜数字游戏(数字炸弹)
  15. FPGA学习之串口篇
  16. 01 - C/C++中的字符串的最后一位是什么?
  17. 语音视频自动生成字幕在线工具介绍
  18. 李建忠设计模式(二)
  19. 超声波测距仪编程_简易超声波测距仪的制作
  20. ROS2 学习古月居ros21讲学习笔记

热门文章

  1. 详解FC交换机基础知识
  2. 上机练习(2019.11.19)
  3. javascript-obfuscator 代码混淆
  4. 2020年的1024程序员节(娱乐小文章)
  5. Android各个版本特性简介
  6. Windows环境下文件夹自动同步的实现
  7. TensorFlow输出矩阵的乘法
  8. 如何搭建一台永久运行的个人服务器?
  9. 代发核心期刊骗局_“代发论文”骗局:近2000人被骗 多数不愿报案
  10. 设计模式-设计原则-开闭原则是目标,里氏代换原则是基础,依赖倒转原则是手段...