gRPC-Go简介

2020-04-26  本文已影响0人  洛杉矶银河

简介

gRPC 是一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。目前提供 C、Java 和 Go 语言版本,分别是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持.

gRPC 基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等特。这些特性使得其在移动设备上表现更好,更省电和节省空间占用

在 gRPC 里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使得您能够更容易地创建分布式应用和服务。与许多 RPC 系统类似,gRPC 也是基于以下理念:定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个接口,并运行一个 gRPC 服务器来处理客户端调用。在客户端拥有一个存根能够像服务端一样的方法。

image

gRPC 客户端和服务端可以在多种环境中运行和交互 - 从 google 内部的服务器到你自己的笔记本,并且可以用任何 gRPC 支持的语言来编写。所以,你可以很容易地用 Java 创建一个 gRPC 服务端,用 Go、Python、Ruby 来创建客户端。此外,Google 最新 API 将有 gRPC 版本的接口,使你很容易地将 Google 的功能集成到你的应用里。

gRPC 基础:Go

本教程提供了 Go 程序员如何使用 gRPC 的指南。

安装gRPC

创建一个空项目,使用go module的方式,Go版本:1.13,
go get -u google.golang.org/grpc

使用 protocol buffers

Google Protocol Buffer( 简称 Protobuf)轻便高效的序列化数据结构的协议,可以用于网络通信和数据存储。
特点:性能高、传输快、维护方便,
一些第三方rpc库都会支持protobuf

安装 Protobuf编译器

https://github.com/protocolbuffers/protobuf/releases/latest
这是protobuf编译器,将.proto文件,转译成protobuf的原生数据结构
找到对应操作系统的zip解压 ,把bin目录加入环境变量

Protobuf github地址:
https://github.com/protocolbuffers/protobuf

golang库所属地址
https://github.com/golang/protobuf

protobuf相关文档
https://developers.google.com/protocol-buffers/docs/gotutorial

安装go Protobuf插件

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

此时会在你的GOPATH 的bin目录下生成可执行文件. protobuf的编译器插件protoc-gen-go

等下我们执行protoc 命令时 就会自动调用这个插件

服务端目录说明

├── services
│   ├── ProdService.go
│   ├── Prod.pb.go
├── pbfiles
│   ├── Prod.proto
|── server.go

定义服务

官方文档里的说明

    service RouteGuide {
        ...
    }

定义商品中间文件Prod.proto

syntax="proto3";
package services;
message ProdRequest{
    int32 prod_id = 1;
    ProdAreas ProdArea = 2;
}

enum ProdAreas{
    A=1;
    B=2;
    C=3;
}

message ProdResponse{
    int32 prod_stock=1;//商品库存
}
service ProdService {
    rpc GetProdStock (ProdRequest) returns (ProdResponse);
}

生成go文件

protoc --go_out=plugins=grpc:../services Prod.proto

服务端实现Prod.proto 中的GetProdStock 方法

ProdService.go

import (
    "context"
)

type ProdService struct {}


func (this *ProdService)GetProdStock(ctx context.Context,request *ProdRequest) (*ProdResponse, error) {
    var stock int32 = 0
    if request.ProdArea == 0{
        stock = 30
    }else if request.ProdArea == ProdAreas_A{
        stock = 31
    }else if request.ProdArea == ProdAreas_B{
        stock = 40
    }else if request.ProdArea == ProdAreas_C{
        stock = 50
    }

    return &ProdResponse{ProdStock:stock},nil
}

服务端创建RPC服务

server.go

package main

import (
    "google.golang.org/grpc"
    "services"
    "net"
)

func main()  {
    rpcServer:=grpc.NewServer()
    services.RegisterProdServiceServer(rpcServer,new(services.ProdService))

    lis,_:=net.Listen("tcp",":8081")

    rpcServer.Serve(lis)


}

客户端拷贝 Prod.pb.go

├── services
│   ├── Prod.pb.go
├── client.go

client.go

package main

import (
    "context"
    "fmt"
    "google.golang.org/grpc"
    "services"
    "log"
)

func main(){

    conn,err:=grpc.Dial(":8081",grpc.WithInsecure())
    if err!=nil{
        log.Fatal(err)
    }
    defer conn.Close()

    prodClient:=services.NewProdServiceClient(conn)
    prodRes,err:=prodClient.GetProdStock(context.Background(),
        &services.ProdRequest{ProdId: 101,ProdArea: services.ProdAreas_A})
    if err!=nil{
        log.Fatal(err)
    }
    fmt.Println(prodRes)//prod_stock:31
     
}
上一篇 下一篇

猜你喜欢

热点阅读