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 

運行結果

 

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