Grpc介紹 — ProToBuf基本使用

RPC(Remote Procedure Call)遠程過程調用,關注筆者的同學應該知道之前筆者出過關于Thrift對應的問題,這次主要來說的是Google開源的Grpc,和Thrift有很大的區(qū)別Grpc是基于HTTP2.0并且依賴protobuf,為什么又推出關于grpc的文章呢?請大家繼續(xù)往下看。

附上:

喵了個咪的博客:w-blog.cn

博文實例demo:GitHub - sunmi-OS/grpc-php-to-golang-demo

grpc官網:grpc / grpc.io

protobuf代碼倉庫:Releases · protocolbuffers/protobuf · GitHub

一,為什么要用grpc它的優(yōu)勢是什么

一個高性能、通用的開源RPC框架,其由Google主要面向移動應用開發(fā)并基于HTTP/2協(xié)議標準而設計,基于ProtoBuf(Protocol Buffers)序列化協(xié)議開發(fā),且支持眾多開發(fā)語言。
gRPC基于HTTP/2標準設計,帶來諸如雙向流控、頭部壓縮、單TCP連接上的多復用請求等特性。這些特性使得其在移動設備上表現(xiàn)更好,更省電和節(jié)省空間占用。

性能 Grpc PK Thrift
借鑒:開源RPC(gRPC/Thrift)框架性能評測 - 滄海一滴 - 博客園

PS:筆者也做了對應的性能測試,后面的文章會附上詳細步驟,通過這個現(xiàn)有的結果一個簡單的結論

從壓測的結果商米我們可以得到以下重要結論:

  • 整體上看,長連接性能優(yōu)于短連接,性能差距在兩倍以上;
  • 對比Go語言的兩個RPC框架,Thrift性能明顯優(yōu)于gRPC,性能差距也在兩倍以上;
  • 對比Thrift框架下的的兩種語言,長連接下Go 與C++的RPC性能基本在同一個量級,在短連接下,Go性能大概是C++的二倍;
  • 兩套RPC框架,以及兩大語言運行都非常穩(wěn)定,5w次請求耗時約是1w次的5倍;

這里主要要回答的一個問題是既然已經用thrift并且性能還是grpc的2倍為什么還要用grpc呢?

這里主要要說到兩個Go的微服務框架,go-kit和istio

  • go-kit 支持thrift但是在thrift的情況下不支持鏈路追蹤
  • istio因為是無侵入式連thrift也不支持

主要的導致這個問題的原因在于thrift的傳輸方式是通過TCP的方式傳輸,對于這些框架想在傳輸過程中加入些鏈路的ID是無法實現(xiàn)的,istio連對于thrift的請求次數感知都做不到,對于grpc因為是基于http2在harder頭上可以做很多補充參數,對于這類微服務框架非常友好。


二,安裝protobuf

安裝protobuf為了生成對應語言的文件必須需要protoc的命名,protoc是c語言的protobuf的命名,有兩種訪問一個是自己編譯:

wget https://github.com/protocolbuffers/protobuf/releases/download/v3.6.1/protobuf-cpp-3.6.1.tar.gz
> tar -zxvf protobuf-cpp-3.6.1.tar.gz
> cd protobuf-3.6.1
> ./configure
> make
> make install
> protoc --version
libprotoc 3.6.1

或者根據更具系統(tǒng)直接使用編譯好的bin文件運行protoc(這里使用的是MAC OSX系統(tǒng))

wget https://github.com/protocolbuffers/protobuf/releases/download/v3.6.1/protoc-3.6.1-osx-x86_64.zip
> tar -zxvf protoc-3.6.1-osx-x86_64.zip
> cd protoc-3.6.1-osx-x86_6/bin
> ./protoc --version
> libprotoc 3.6.1

安裝好了我們就要來運行下測試程序了


三,Golang 環(huán)境準備

不得不說Go是Google的親兒子,自然Grpc的支持不會差依賴只需要一個命令就可以(這里使用的是go 1.11版本):

> go get google.golang.org/grpc

如果大家報錯,原因是這個代碼已經轉移到github上面了,但是代碼里面的包依賴還是沒有修改,還是google.golang.org這種,所以有的不能使用go get的方式安裝,可以使用以下安裝方式:

> git clone https://github.com/grpc/grpc-go.git $GOPATH/src/google.golang.org/grpc
> git clone https://github.com/golang/net.git $GOPATH/src/golang.org/x/net
> git clone https://github.com/golang/text.git $GOPATH/src/golang.org/x/text
> git clone https://github.com/golang/sys.git $GOPATH/src/golang.org/x/sys
> go get -u github.com/golang/protobuf/{proto,protoc-gen-go}
> git clone https://github.com/google/go-genproto.git $GOPATH/src/google.golang.org/genproto
> cd $GOPATH/src/
> go install google.golang.org/grpc

先使用筆者的準備好的:

> cd $GOPATH/src
> mkdir -p grpc-php-to-golang-demo/protobuf
> cd grpc-php-to-golang-demo/protobuf
> vim helloworld.proto

文件內容如下:

syntax = "proto3";

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

package helloworld;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

生成對應的文件:

> mkdir -p go-server/helloworld
> protoc --go_out=plugins=grpc:./go-server/helloworld ./helloworld.proto
> cd go-server/helloworld/
> ll
total 16
drwxr-xr-x  3 wenzhenxi  staff    96  2 15 14:24 ./
drwxr-xr-x  3 wenzhenxi  staff    96  2 15 14:23 ../
-rw-r--r--  1 wenzhenxi  staff  6915  2 15 14:24 helloworld.pb.go

編寫服務端和客戶端Go程序:

> cd $GOPATH/src/grpc-php-to-golang-demo
> mkdir -p golang/holleworld
> cd golang/holleworld

服務端:

> vim server.go 

package main

import (
    "log"
    "net"

    pb "grpc-php-to-golang-demo/protobuf/go-server/helloworld"

    "google.golang.org/grpc"
    "golang.org/x/net/context"
    "google.golang.org/grpc/reflection"
)

const (
    port = ":50051"
)

// server is used to implement helloworld.GreeterServer.
type server struct{}

// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
    return &pb.HelloReply{Message: "Hello " + in.Name}, 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{})
    // Register reflection service on gRPC server.
    reflection.Register(s)
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}

客戶端:

> vim client.go

package main

import (
    "log"
    "os"
    "time"

    pb "grpc-php-to-golang-demo/protobuf/go-server/helloworld"

    "google.golang.org/grpc"
    "golang.org/x/net/context"
)

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

func main() {
    // Set up a connection to the server.
    conn, err := grpc.Dial(address, grpc.WithInsecure())
    if err != nil {
        log.Fatalf("did not connect: %v", err)
    }
    defer conn.Close()
    c := pb.NewGreeterClient(conn)

    // Contact the server and print out its response.
    name := defaultName
    if len(os.Args) > 1 {
        name = os.Args[1]
    }

    go func() {
        r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name})
        if err != nil {
            log.Fatalf("could not greet: %v", err)
        }
        log.Printf("Greeting: %s", r.Message)
    }()

    time.Sleep(10 * time.Second)

}

運行測試:

> go build server.go
> go build client.go
./server
./client
2019/02/15 14:35:35 Greeting: Hello world

此時在go to go的場景就調用通了

最終產物可以參考demoGitHub - sunmi-OS/grpc-php-to-golang-demo

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • gRPC 是一個高性能、通用的開源RPC框架,基于HTTP/2協(xié)議標準和Protobuf序列化協(xié)議開發(fā),支持眾多的...
    小波同學閱讀 19,573評論 6 19
  • 原文出處:gRPC gRPC分享 概述 gRPC 一開始由 google 開發(fā),是一款語言中立、平臺中立、開源的遠...
    小波同學閱讀 7,325評論 0 18
  • 原文連接: 一文了解RPC以及gRPC基于Golang和Java的簡單實現(xiàn) 一:什么是RPC 簡介:RPC:Re...
    賈順閱讀 8,953評論 2 12
  • ProtoBuf 是一套接口描述語言(IDL)和相關工具集(主要是 protoc,基于 C++ 實現(xiàn)),類似 Ap...
    糖果果老師閱讀 3,574評論 0 3
  • 敬愛的李老師,智慧的教授,親愛的家人們: 大家好!我是來自長興南方眼視光中心的楊軍微,我是王院長的人。今天...
    楊軍微閱讀 276評論 0 1