转载请注明来自ChenJiehua《GRPC快速入门》

GRPC是一个高性能、通用的开源RPC框架,基于HTTP/2协议标准和Protobuf序列化协议开发,支持众多的开发语言。

概述

在GRPC框架中,客户端可以像调用本地对象一样直接调用位于不同机器的服务端方法,如此我们就可以非常方便的创建一些分布式的应用服务。

在服务端,我们实现了所定义的服务和可供远程调用的方法,运行一个gRPC server来处理客户端的请求;在客户端,gRPC实现了一个stub(可以简单理解为一个client),其提供跟服务端相同的方法。

GRPC快速入门-LMLPHP

gRPC使用protocol buffers作为接口描述语言(IDL)以及底层的信息交换格式,一般情况下推荐使用 proto3因为其能够支持更多的语言,并减少一些兼容性的问题。

简单示例如下:

// 定义了一个服务 Greeter
service Greeter {
// 定义方法 SayHello
rpc SayHello (HelloRequest) returns (HelloReply) {}
} // request
message HelloRequest {
string name = 1;
} // response
message HelloReply {
string message = 1;
}

gRPC使用 protoc 和一个插件来将proto定义的内容生成客户端/服务端的代码。

Proto定义

helloworld.proto

syntax = "proto3";

option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto"; package helloworld; // The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (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;
}

Go示例

安装grpc和protobuf

1、gRPC要求 Go 版本 >= 1.6

2、安装 gRPC:

$ go get -u -v google.golang.org/grpc

3、安装 Protocol Buffers v3:

github下载预编译的protoc,然后安装 protoc-gen-go:

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

生成 gRPC代码

$ protoc -I. --go_out=plugins=grpc:. helloworld.proto

Server 代码

server.go

package main

import (
"log"
"net" "golang.org/x/net/context"
"google.golang.org/grpc"
pb "google.golang.org/grpc/examples/helloworld/helloworld"
"google.golang.org/grpc/reflection"
) const (
port = ":50051"
) // server is used to implement helloworld.GreeterServer.
type server struct{} // SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
return &pb.HelloReply{Message: "Hello " + in.Name}, nil
} func main() {
lis, err := net.Listen("tcp", port)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterGreeterServer(s, &server{})
// Register reflection service on gRPC server.
reflection.Register(s)
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}

Client 代码

client.go

package main

import (
"log"
"os"
"time" "golang.org/x/net/context"
"google.golang.org/grpc"
pb "google.golang.org/grpc/examples/helloworld/helloworld"
) const (
address = "localhost:50051"
defaultName = "world"
) func main() {
// Set up a connection to the server.
conn, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := pb.NewGreeterClient(conn) // Contact the server and print out its response.
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("Greeting: %s", r.Message)
}

Python示例

安装grpc和protobuf

1、新建个虚拟环境:

$ pip install virtualenv
$ virtualenv venv
$ source venv/bin/activate
$ pip install -U pip

2、在虚拟环境中安装grpc和protobuf:

$ pip install grpcio

3、安装 grpc tools:

python的grpc tools包含了protoc及其插件,用来生成客户端和服务端代码

$ pip install grpcio-tools

4、安装 grpc reflection:

grpc reflection 使得服务端支持 grpc_cli 进行调试

$ pip install grpcio-reflection

生成 gRPC 代码

$ python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. helloworld.proto

Server 代码

server.py

"""The Python implementation of the GRPC helloworld.Greeter server."""

from concurrent import futures
import time import grpc
from grpc.reflection.v1alpha import reflection<br>
import helloworld_pb2
import helloworld_pb2_grpc _ONE_DAY_IN_SECONDS = 60 * 60 * 24 class Greeter(helloworld_pb2_grpc.GreeterServicer): def SayHello(self, request, context):
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
reflection.enable_server_reflection([h.service_name() for h in server._state.generic_handlers], server)
server.add_insecure_port('[::]:50051')
server.start()
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(0) if __name__ == '__main__':
serve()

Client 代码

client.py

"""The Python implementation of the GRPC helloworld.Greeter client."""

from __future__ import print_function

import grpc

import helloworld_pb2
import helloworld_pb2_grpc def run():
channel = grpc.insecure_channel('localhost:50051')
stub = helloworld_pb2_grpc.GreeterStub(channel)
response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))
print("Greeter client received: " + response.message) if __name__ == '__main__':
run()

grpc_cli命令行工具

为了使用 grpc_cli ,我们需要从源码进行安装。

1、从github获取源码:

 $ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc
$ cd grpc
$ git submodule update --init

2、编译 grpc_cli:

# Linux下需要 gflags
$ sudo apt-get install libgflags-dev
$ make grpc_cli

3、使用 grpc_cli:

# 查看所有的服务
$ grpc_cli ls localhost:50051 # 查看 Greeter 服务的详细信息
$ grpc_cli ls localhost:50051 helloworld.Greeter -l # 查看 Greeter.SayHello 方法的详细信息
$ grpc_cli ls localhost:50051 helloworld.Greeter.SayHello -l # 远程调用
$ grpc_cli call localhost:50051 SayHello "name: 'gRPC CLI'"

参考:

05-27 09:40