gRPC最佳入门教程,Golang/Python/PHP多语言讲解

目录

  • 一、gRPC是什么?
  • 二、Protocol Buffers是什么?
  • 三、需求:开发健身房服务
  • 四、最佳实践
    • Golang

      • 1. 安装protoc
      • 2. 安装protoc-gen-go
      • 3. 安装grpc包
      • 4. 生成代码
      • 5. 定义服务端
      • 6. 定义客户端
      • 7. 运行代码
    • Python
      • 1. 安装grpc包
      • 2. 安装protobuf
      • 3. 安装grpc的protobuf编译工具
      • 4. 生成代码
      • 5. 定义服务端
      • 6. 定义客户端
      • 7. 运行代码
    • PHP
      • 1. 安装protoc
      • 2. 安装grpc扩展
      • 3. 安装protobuf扩展
      • 4. 安装生成代码的插件grpc_php_plugin
      • 5. 生成代码
      • 6. 定义客户端文件
      • 7. 运行代码

一、gRPC是什么?

gRPC,其实就是RPC的一种,前面带了一个g,代表是RPC中的大哥,龙头老大的意思,另外g也有global的意思,意思是全球化比较fashion。

常见的RPC框架有如下:

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

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

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

二、Protocol Buffers是什么?

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

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

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

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

定义了一个健身房(Gym),然后提供一个叫健身(Bodybuilding)的服务
使用该服务,需要指定人(Person),人有名字和动作两个属性,下面新建一个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

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

2. 安装protoc-gen-go

protoc依赖该工具生成代码

go get -u github.com/golang/protobuf/{proto,protoc-gen-go}

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
go get -u github.com/golang/protobuf/{proto,protoc-gen-go}
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. 生成代码

# 生成服务端代码
protoDir="../protos"
outDir="../languages/golang/gym"
protoc -I ${protoDir}/ ${protoDir}/*proto --go_out=plugins=grpc:${outDir}

protoc工具参数解释:

  • -I: 指定import路径,可以指定多个-I参数,编译时按顺序查找,不指定默认当前目录
  • -go_out:指定og语言的访问类
  • plugins:指定依赖的插件

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

5. 定义服务端

package main

import (
 "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 main

import (
 "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

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

Python

1. 安装grpc包

pip install grpcio

2. 安装protobuf

pip install protobuf

3. 安装grpc的protobuf编译工具

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

pip install grpcio-tools

4. 生成代码

#!/usr/bin/env bash

protoDir="../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_pb2

class 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_pb2

def 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

PHP

1. 安装protoc

地址:https://github.com/google/protobuf/releases
我是mac,用的是这个地址:https://github.com/protocolbuffers/protobuf/releases/download/v3.11.4/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 bash

protoDir="../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. 运行代码

OK,到这里,分别演示了Golang、Python、PHP使用gRPC的例子,相信你也已经学会了。

原文地址:https://www.cnblogs.com/chenqionghe/p/12394845.html

时间: 2024-11-14 11:11:56

gRPC最佳入门教程,Golang/Python/PHP多语言讲解的相关文章

Python10分钟入门教程,Python入门神图一张

这篇文章主要介绍了Python 10分钟入门教程,分享一张Python入门神图一张,具有一定的参考价值,感兴趣的小伙伴们可以参考一下| 初试牛刀 假设你希望学习Python这门语言,却苦于找不到一个简短而全面的入门教程.那么本教程将花费十分钟的时间带你走入Python的大门.本文的内容介于教程(Toturial)和速查手册(CheatSheet)之间,因此只会包含一些基本概念.很显然,如果你希望真正学好一门语言,你还是需要亲自动手实践的.在此,我会假定你已经有了一定的编程基础,因此我会跳过大部分

Python基础入门教程,Python学习路线图

给大家整理的这套python学习路线图,按照此教程一步步的学习来,肯定会对python有更深刻的认识.或许可以喜欢上python这个易学,精简,开源的语言.此套教程,不但有视频教程,还有源码分享,让大家能真正打开python的大门,进入这个领域.现在互联网巨头,都已经转投到人工智能领域,而人工智能最好的编程语言就是python,未来前景显而易见.黑马程序员是国内最早开设人工智能的机构. 一.首先先推荐一个教程 8天深入理解python教程:http://pan.baidu.com/s/1kVNm

Python入门教程(2)Python 变量,数据类型用户交互与基本运算

一 变量 什么是变量 #变量即变化的量,核心是"变"与"量"二字,变即变化,量即衡量状态. 为什么要有变量 #程序执行的本质就是一系列状态的变化,变是程序执行的直接体现,所以我们需要有一种机制能够反映或者说是保存下来程序执行时状态以及状态的变化. #比如: 英雄的等级为1,打怪升级(变)为10 僵尸的存活状态True,被植物打死了,于是变为False 人的名字为Albert,也可以修改为马一特 如何定义变量 #变量名(相当于门牌号,指向值所在的空间),等号,变量值

Python爬虫入门教程 56-100 python爬虫高级技术之验证码篇2-开放平台OCR技术

今日的验证码之旅 今天你要学习的验证码采用通过第三方AI平台开放的OCR接口实现,OCR文字识别技术目前已经比较成熟了,而且第三方比较多,今天采用的是百度的. 注册百度AI平台 官方网址:http://ai.baidu.com/ 接下来申请 接下来创建一个简单应用之后,就可以使用了,我们找到 阅读文字识别相关文档 你需要具备基本的阅读第三方文档的能力,打开我们需要的文档 https://cloud.baidu.com/doc/OCR/OCR-API.html#.E9.80.9A.E7.94.A8

IOS入门教程(三)-C语言特性

//3.C语言特性 //3.1函数的定义 //函数返回类型 函数名(参数){ //dosomthing //}一般的函数定义都是这样的, //有一种古老的函数定义方式,另外起一行对参数进行说明 void printMesg(msg,loopNum) int loopNum; int msg; { int i; for(i = 0;i<loopNum;i++){ printf("第%d次循环%d \n",i+1,msg); } } //3.2函数声明 //函数的声明是用于函数的使用

2015年最新Android基础入门教程目录(完结版)

2015年最新Android基础入门教程目录(完结版) 标签(空格分隔): Android基础入门教程 前言: 关于<2015年最新Android基础入门教程目录>终于在今天落下了帷幕,全套教程 共148节已编写完毕,附上目录,关于教程的由来,笔者的情况和自学心得,资源分享 以及一些疑问等可戳:<2015最新Android基础入门教程>完结散花~ 下面是本系列教程的完整目录: 第一章:环境搭建与开发相关(已完结 10/10) Android基础入门教程--1.1 背景相关与系统架构

2015年最新Android基础入门教程目录(临时版)

2015年最新Android基础入门教程目录(临时版) 标签(空格分隔): Android基础入门教程 前言: 嗯,昨晚又给人盗号了,博客上被发表了十几篇黄贴-然后目录给管理误删了,再发一次 后来协商后发现实被设密保问题了,建议各位用csdn的朋友密保自己设置一波~ 密保问题已修改回来了,应该不会再被盗号了-人怕出名猪怕壮哈~下次如果发现博客被封 告知下小猪,如何很急的话可以先到w3c鸟巢菜鸟教程上看Android基础入门教程 经过站长FK进行排版的,可能阅读体验会比csdn好很多!内容基本是同

哪有python开发语言入门教程免费下载?

人工智能时代,如果不想被机器人取代,最应该掌握的是编程.Python作为连续10年最受欢迎的编程语言,不但能开发Google .豆瓣等大型网站,还是人工智能领域的第一语言.那么,我猜你想问哪里有python开发语言入门教程. 千锋Python基础教程:http://pan.baidu.com/s/1qYTZiNE Python课程教学高手晋级视频总目录:http://pan.baidu.com/s/1hrXwY8k Python课程windows知识点:http://pan.baidu.com/

PySide——Python图形化界面入门教程(六)

PySide——Python图形化界面入门教程(六) ——QListView和QStandardItemModel 翻译自:http://pythoncentral.io/pyside-pyqt-tutorial-qlistview-and-qstandarditemmodel/ 上一个教程中,我们讨论了Qt的QListWidget类,它用来实现简单的单列列表框(list boxes).然而,我们还需要更加灵活的widget来实现列表,Qt为此提供了QListView 来实现多种多样的项.它是一