go python php_Golang/Python/PHP带你彻底学会gRPC

一、gRPC是什么?

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

常见的RPC框架有如下:

gRPC。谷歌出品

Thrift。Apache出品

Dubbo。阿里出品,也是一个微服务框架

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

使用Protocal Buffers这个强大的序列化工具集和语言

grpc可以跨语言使用

安装简单,扩展方便(用该框架每秒可达到百万个RPC)

基于HTTP2协议

二、Protocol Buffers是什么?

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

Protocol Buffers序列化后的数据是不可读的,因为是二进制流

使用Protocol Buffer需要事先定义数据的格式(.proto 协议文件),还原一个序列化之后的数据需要使用到这个数据格式

Protocol Buffer 比 XML、JSON快很多,因为是基于二进制流,比字符串更省带宽,传入速度快

Protocol Buffer语法:查看官方文档

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

定义了一个健身房Gym,然后提供一个服健身Bodybuilding的服务,使用该服务,需要人(名称和训练动作)

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目录生成了该代码

1025a58f9203394a69fec3ef3d1415f5.png

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

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

a4dbf3f788922a3743f9b7fdd1f67e4b.png

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

45275dee4a8be33ed7a75b8343cddf75.png

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

3d7276086cdefe08f64a07c05ad7d2dd.png

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文件中看到)

3a0a6a854100e1461c5db440b0bd5866.png

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

安装完成画风

7369af1d1914392f45efda1dc1af48f5.png

最终会在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

生成代码如下

fd134fe794ad78a249e6d07d95d0c1ec.png

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

/**

* 客户端使用示例

* @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.运行代码

0b2f59d111d87cbd316d61759b5b8ce4.png

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值