Go语言 gRPC 实践(一)

介绍

RPC是远程过程调用(Remote Procedure Call)的缩写形式。SAP系统RPC调用的原理其实很简单,有一些类似于三层构架的C/S系统,第三方的客户程序通过接口调用SAP内部的标准或自定义函数,获得函数返回的数据进行处理后显示或打印。

gRPC,A high-performance, open-source universal RPC framework,Google开源的高性能的RPC框架,基于ProtoBuf序列化协议进行开发,多种语言支持(Golang、PHP、C++、Java等)支持,面向HTTP/2标准设计。

官方文档:https://grpc.io/about/

应用场景

  • 低延时、高可用的分布式系统
  • 使用ProtoBuf,独立于语言的协议
  • 负载均衡,日志系统,监控系统等

Protobuf

是Google开发的一个网络通信协议,提供了高效率的序列化和反序列化机制,序列化就是把对象转换成二进制数据发送给服务端,反序列化就是将收到的二进制数据转换成对应的对象。官方版本支持Go,C++,Java,Python等语言。

Protobuf优点

  • 体积小,效率高
  • 使用简单,兼容性好,维护简单
  • 加密性好
  • 跨平台

安装ProtoBuf

go get -u google.golang.org/grpc

获取编译器Protoc

wget https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz
tar -xzvf protobuf-2.6.1.tar.gz
cd protobuf-2.6.1
./configure --prefix=/usr/local/protobuf
make
make install

vim /etc/profile
export PATH=$PATH:/usr/local/protobuf/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/protobuf/lib

获取 protoc-gen-go

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

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

go build

go install

获取proto库

go get github.com/golang/protobuf/proto

cd github.com/golang/protobuf/proto

go build

go install

实例

says_rpc.proto

syntax = "proto2";

// This file relies on plugins to generate service code.
option cc_generic_services = true;
option java_generic_services = true;
option py_generic_services = true;

package gg_rpc;

option go_package = "pb_models/gg_rpc";


message RpcRequest {
    required string name = 1;
}

message RpcReply {
    required string message = 1;
}

service Greeter {
    rpc RpcCall(RpcRequest) returns (RpcReply) ;
}

rpc_server.go

package main

import (
    "context"
    "fmt"
    "google.golang.org/grpc"
    pb "pb_models/gg_rpc"
    "log"
    "net"
    "github.com/golang/protobuf/proto"
)

const(
    Port = ":10010"
)

type server struct {}

func (s *server) RpcCall(Ctx context.Context, In *pb.RpcRequest) (*pb.RpcReply, error) {
    log.Printf("Received : %v", In.GetName())
    Msg := fmt.Sprintf("Hello : %v " , In.GetName())
    return &pb.RpcReply{Message: proto.String(Msg)}, nil 
}

func main() {
    Socket, Err := net.Listen("tcp", Port)
    if Err != nil {
        log.Fatalf("failed to listen : %v .", Err)
    }   

    Rpc := grpc.NewServer()

    pb.RegisterGreeterServer(Rpc, &server{})

    if Err := Rpc.Serve(Socket); Err != nil {
        log.Fatalf("failed to service : %v .", Err)
    }   
}

rpc_client.go

package main

import (
        "context"
        "google.golang.org/grpc"
        pb "pb_models/gg_rpc"
        "log"
        "fmt"
        "os"
        "github.com/golang/protobuf/proto"
        "time"
)

const (
        Address = "localhost:10010"
        DefaultName = "Carter"
)

func main() {

        Conn, Err := grpc.Dial(Address, grpc.WithInsecure())
        if Err != nil {
                log.Fatalf("did not connect : %v .", Err)
        }

        defer Conn.Close()

        Client := pb.NewGreeterClient(Conn)
        fmt.Println("grpc client start.")

        Name := DefaultName
        if len(os.Args) > 1 {
                Name = os.Args[1]
        }

        Ctx, Cancel := context.WithTimeout(context.Background(), time.Second)
        defer Cancel()

        RpcResult, RpcError := Client.RpcCall(Ctx, &pb.RpcRequest{Name : proto.String(Name)})
        if RpcError != nil {
                log.Fatalf("could not greet %v .", RpcError)
        }

        log.Printf("Greeting: %v .", RpcResult.GetMessage())
}

编译命令

protoc --go_out=plugins=grpc:. gg_rpc.proto

go build rpc_server.go
go build rpc_client.go 

运行结果

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章