gRPC初体验

Posted 爱好历史的程序员

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了gRPC初体验相关的知识,希望对你有一定的参考价值。

gRPC是可以在任何环境中运行的现代开源高性能RPC框架。它可以通过可插拔的支持来有效地连接数据中心内和跨数据中心的服务,以实现负载平衡,跟踪,运行状况检查和身份验证。它也适用于分布式计算的最后一英里,以将设备,移动应用程序和浏览器连接到后端服务。

安装protocol buffer 编译器

mac:

 
   
   
 
  1. brew install protobuf

其他系统可以尝试编译安装

  • protocolbuffers/protobuf

安装gprc

 
   
   
 
  1. go get -u google.golang.org/grpc

安装protoc-gen-go插件

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

使用

新建hello目录,进入后执行:

 
   
   
 
  1. protoc --proto_path hello/ --go_out=plugins=grpc:hello hello.proto

会看到hello目录下生成了hello.pb.go文件。

当然,其中的 hello.proto 是预先自定义在hello文件夹下的,如:

 
   
   
 
  1. syntax = "proto3"; //语法声明


  2. package hello; //包名


  3. // 定义服务

  4. service Greeter {

  5. rpc SayHello (HelloRequest) returns (HelloReply) {}

  6. }


  7. // 请求数据格式

  8. message HelloRequest {

  9. string name = 1;

  10. }


  11. // 响应数据格式

  12. message HelloReply {

  13. string message = 1;

  14. }

server

新建server目录, golang例子代码来自:https://github.com/grpc/grpc-go/tree/master/examples/helloworld

 
   
   
 
  1. // main.go

  2. package main


  3. import (

  4. "context"

  5. "log"

  6. "net"


  7. "google.golang.org/grpc"

  8. pb "local.com/sai/game/grpc/hello"

  9. )


  10. const (

  11. port = ":50051"

  12. )


  13. // server is used to implement helloworld.GreeterServer.

  14. type server struct {

  15. pb.UnimplementedGreeterServer

  16. }


  17. // SayHello implements helloworld.GreeterServer

  18. func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {

  19. log.Printf("Received: %v", in.GetName())

  20. return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil

  21. }


  22. func main() {

  23. lis, err := net.Listen("tcp", port)

  24. if err != nil {

  25. log.Fatalf("failed to listen: %v", err)

  26. }

  27. s := grpc.NewServer()

  28. pb.RegisterGreeterServer(s, &server{})

  29. if err := s.Serve(lis); err != nil {

  30. log.Fatalf("failed to serve: %v", err)

  31. }

  32. }

client

go client

 
   
   
 
  1. // client.go

  2. package main


  3. import (

  4. "context"

  5. "log"

  6. "os"

  7. "time"


  8. "google.golang.org/grpc"

  9. pb "local.com/sai/game/grpc/hello"

  10. )


  11. const (

  12. address = "127.0.0.1:50051"

  13. defaultName = "13sai"

  14. )


  15. func main() {

  16. // Set up a connection to the server.

  17. conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock())

  18. if err != nil {

  19. log.Fatalf("did not connect: %v", err)

  20. }

  21. defer conn.Close()

  22. c := pb.NewGreeterClient(conn)


  23. // Contact the server and print out its response.

  24. name := defaultName

  25. if len(os.Args) > 1 {

  26. name = os.Args[1]

  27. }

  28. ctx, cancel := context.WithTimeout(context.Background(), time.Second)

  29. defer cancel()

  30. r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name})

  31. if err != nil {

  32. log.Fatalf("could not greet: %v", err)

  33. }

  34. log.Printf("Greeting: %s", r.GetMessage())

  35. }`

php client

扩展安装

  • grpc扩展下载

  • profo

下载安装合适版本的扩展即可,记得别忘记在php.ini中加入:

 
   
   
 
  1. extension=grpc.so

  2. extension=protobuf.so

自动生成代码

 
   
   
 
  1. protoc --php_out=client hello/hello.proto

会看到client目录下生成了GPBMetadata和Hello两个目录。

如果你对grpc较熟练,可以直接进行代码编写:

 
   
   
 
  1. <?php

  2. require __DIR__ . '/vendor/autoload.php';


  3. class Client extends \Grpc\BaseStub{


  4. public function __construct($hostname, $opts, $channel = null) {

  5. parent::__construct($hostname, $opts, $channel);

  6. }


  7. /**

  8. * rpc SayHello(HelloRequest) returns (HelloReply) {}

  9. * 方法名尽量和 (gprc 定义 Greeter 服务)的方法一样

  10. * 用于请求和响应该服务

  11. */

  12. public function SayHello(\Hello\HelloRequest $argument){

  13. // (/hello.Greeter/SayHello) 是请求服务端那个服务和方法,基本和 proto 文件定义一样

  14. return $this->_simpleRequest('/hello.Greeter/SayHello',

  15. $argument,

  16. ['\Hello\HelloReply', 'decode']

  17. );

  18. }


  19. }


  20. //用于连接 服务端

  21. $client = new \Client('127.0.0.1:50051', [

  22. 'credentials' => Grpc\ChannelCredentials::createInsecure()

  23. ]);


  24. //实例化 TestRequest 请求类

  25. $request = new \Hello\HelloRequest();

  26. $request->setName("fairy");


  27. //调用远程服务

  28. $get = $client->SayHello($request)->wait();


  29. //返回数组

  30. //$reply 是 TestReply 对象

  31. //$status 是数组

  32. list($reply, $status) = $get;


  33. echo $reply->getMessage().PHP_EOL;

  34. // print_r($client->SayHello($request));

当然,也可以使用grpcphpplugin插件生成。

- grpc-php

grpcphpplugin插件

clone太慢可以使用码云

 
   
   
 
  1. git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc

  2. cd grpc

  3. #这一步很慢,暂未找到什么好方法

  4. git submodule update --init

  5. make grpc_php_plugin

新建php-client,再来自动生成:

 
   
   
 
  1. protoc -I=./hello hello.proto --php_out=./php-client/ --grpc_out=php-client/ --plugin=protoc-gen-grpc=/Users/wangzetao/www/grpc1/bins/opt/grpc_php_plugin

会发现比上面自动生成多了一个GreeterClient.php

 
   
   
 
  1. <?php

  2. // client.php

  3. require __DIR__ . '/vendor/autoload.php';


  4. //用于连接 服务端

  5. $client = new \Hello\GreeterClient('127.0.0.1:50051', [

  6. 'credentials' => Grpc\ChannelCredentials::createInsecure()

  7. ]);


  8. //实例化 TestRequest 请求类

  9. $request = new \Hello\HelloRequest();

  10. $request->setName("world");


  11. //调用远程服务

  12. $get = $client->SayHello($request)->wait();


  13. //返回数组

  14. //$status 是数组

  15. list($reply, $status) = $get;


  16. echo $reply->getMessage().PHP_EOL;

  17. // print_r($client->SayHello($request));

运行测试

go run grpc/server/main.go

go run grpc/client/main.go

go run grpc/client/client.php

go run grpc/client/php-client.php

gRPC初体验完成了,本次只是小小的使用了一下子,后续感兴趣的话可以深入学习一下。文中如有错误,欢迎指出交流。





往期技术文章






·END·

 爱好历史的程序员

分享编程知识,诉说魏晋风流

微信号:mijisai



以上是关于gRPC初体验的主要内容,如果未能解决你的问题,请参考以下文章

gRPC初体验

[Go][gRPC]mock初体验

.NET gRPC核心功能初体验

Grpc-Gateway 初体验

干货.NET Core微服务之Grpc初体验

vs code初体验