gRPC是什么

gRPC是一个高性能、开源、通用的 RPC框架 。基于HTTP/2协议标准设计开发,默认采用Protocol Buffers数据序列化协议(Protocol Buffers基本语法),支持多种开发语言。gRPC提供了一种简单的方法来精确的定义服务,并且为客户端和服务端自动生成可靠的功能库

gRPC应用场景

在gRPC客户端可以直接调用不通服务器上的远程程序,就想调用本地程序一样,很容易构建分布式应用和服务。和很多RPC系统一样,服务负责实现定义好的接口并处理客户端请求,客户端根据接口描述直接调用需要的服务。客户端和服务器可以分别使用gRPC支持的不同语言实现

官方配置教程链接

 

gPRC列子 hello gRPC

编写流程

  1. 编写.proto描述文件  
  2. 编译生成.pb.go文件  
  3. 客户端实现约定的接口并提供服务  
  4. 客户端按照约定调用方法请求服务

代码示例 
helloworld.proto   rpc服务描述文件

syntax = "proto3";

option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";

package helloworld;

// 问候服务定义。
service Greeter {
  // 发送问候
  rpc SayHello (HelloRequest) returns (HelloReply) {}
  // 再次发送问候
  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}

// 包含用户名的请求消息
message HelloRequest {
  string name = 1;
}

// 包含问候语的响应消息
message HelloReply {
  string message = 1;
}

文件中定义了一个Greeter Service 该服务包含了一个SayHello方法和SayHelloAgain方法 同时声明了HelloRequest和HelloReply消息结构用于请求和响应。客户端使用HelloRequest参数调用SayHello方法请求服务端 服务端响应HelloReply消息
使用命令protoc -I helloworld/ helloworld/helloworld.proto --go_out=plugins=grpc:helloworld生成Golang源文件 helloworld..pb.go,源文件中包含消息传递的请求和响应结构。服务端注册对象的方法 创建客户端 以及调用服务端方法

服务器端代码

//go:生成 protoc -I ../helloworld --go_out=plugins=grpc:../helloworld ../helloworld/helloworld.proto

// Package main implements a server for Greeter service.
package main

import (
    "context"
    "log"
    "net"

    "google.golang.org/grpc"
    pb "google.golang.org/grpc/examples/helloworld/helloworld"
)

const (
    port = ":50051"
)

// 服务器用于实现helloworld.greeter服务器。
type server struct{}

// say hello实现helloworld.greeter服务器
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
    log.Printf("Received: %v", in.GetName())
    return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil
}

func (s *server) SayHelloAgain(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
    return &pb.HelloReply{Message: "Hello again " + in.GetName()}, 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{})
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }

}

客户端代码 

// Package main implements a client for Greeter service.
package main

import (
    "context"
    "log"
    "os"
    "time"

    "google.golang.org/grpc"
    pb "google.golang.org/grpc/examples/helloworld/helloworld"
)

const (
    address     = "localhost:50051"
    defaultName = "world"
)

func main() {
    // 建立到服务器的连接
    conn, err := grpc.Dial(address, grpc.WithInsecure())
    if err != nil {
        log.Fatalf("did not connect: %v", err)
    }
    defer conn.Close()
    c := pb.NewGreeterClient(conn)

    // 连接服务器并打印出其响应
    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.GetMessage())
    r, err = c.SayHelloAgain(ctx, &pb.HelloRequest{Name: name})
    if err != nil {
        log.Fatalf("could not greet: %v", err)
    }
    log.Printf("Greeting: %s", r.GetMessage())
}

然后分别运行服务器端和客户端
批注 2019-09-08 162343.png

可以看到程序已经ok!

Last modification:September 9th, 2019 at 07:13 pm
如果觉得我的文章对你有用,请随意赞赏