久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

ProtoBuf 與 gRPC 你需要知道的知識(shí)

 紫火神兵 2017-07-06

ProtoBuf 是一套接口描述語(yǔ)言(IDL)和相關(guān)工具集(主要是 protoc,,基于 C++ 實(shí)現(xiàn)),,類似 Apache 的 Thrift)。用戶寫好 .proto 描述文件,,之后使用 protoc 可以很容易編譯成眾多計(jì)算機(jī)語(yǔ)言(C++,、JavaPython,、C#,、Golang 等)的接口代碼。這些代碼可以支持 gRPC,,也可以不支持,。

gRPC 是 Google 開源的 RPC 框架和庫(kù),已支持主流計(jì)算機(jī)語(yǔ)言,。底層通信采用 gRPC 協(xié)議,,比較適合互聯(lián)網(wǎng)場(chǎng)景。gRPC 在設(shè)計(jì)上考慮了跟 ProtoBuf 的配合使用,。

兩者分別解決的不同問題,可以配合使用,,也可以分開,。

典型的配合使用場(chǎng)景是,,寫好 .proto 描述文件定義 RPC 的接口,然后用 protoc(帶 gRPC 插件)基于 .proto 模板自動(dòng)生成客戶端和服務(wù)端的接口代碼,。

ProtoBuf

需要工具主要包括:

  • 編譯器:protoc,,以及一些官方?jīng)]有帶的語(yǔ)言插件;
  • 運(yùn)行環(huán)境:各種語(yǔ)言的 protobuf 庫(kù),,不同語(yǔ)言有不同的安裝來(lái)源,;

語(yǔ)法類似 C++ 語(yǔ)言,可以參考 語(yǔ)言規(guī)范,。

比較核心的,,message 是代表數(shù)據(jù)結(jié)構(gòu)(里面可以包括不同類型的成員變量,包括字符串,、數(shù)字,、數(shù)組、字典……),,service代表 RPC 接口,。變量后面的數(shù)字是代表進(jìn)行二進(jìn)制編碼時(shí)候的提示信息,1~15 表示熱變量,,會(huì)用較少的字節(jié)來(lái)編碼,。另外,支持導(dǎo)入,。

默認(rèn)所有變量都是可選的(optional),,repeated 則表示數(shù)組。主要 service rpc 接口只能接受單個(gè) message 參數(shù),,返回單個(gè) message,;

syntax = "proto3";
package hello;

message HelloRequest {
  string greeting = 1;
}

message HelloResponse {
  string reply = 1;
  repeated int32 number=4;
}

service HelloService {
  rpc SayHello(HelloRequest) returns (HelloResponse){}
}

編譯最關(guān)鍵參數(shù)是指定輸出語(yǔ)言格式,例如,,python 為 --python_out=OUT_DIR,。

一些還沒有官方支持的語(yǔ)言,可以通過安裝 protoc 對(duì)應(yīng)的 plugin 來(lái)支持,。例如,,對(duì)于 Go 語(yǔ)言,可以安裝

$ go get -u github.com/golang/protobuf/{protoc-gen-go,proto} // 前者是 plugin,;后者是 go 的依賴庫(kù)

之后,,正常使用 protoc --go_out=./ hello.proto 來(lái)生成 hello.pb.go,會(huì)自動(dòng)調(diào)用 protoc-gen-go 插件,。

ProtoBuf 提供了 Marshal/Unmarshal 方法來(lái)將數(shù)據(jù)結(jié)構(gòu)進(jìn)行序列化操作,。所生成的二進(jìn)制文件在存儲(chǔ)效率上比 XML 高 3~10 倍,并且處理性能高 1~2 個(gè)數(shù)量級(jí)。

gRPC

工具主要包括:

  • 運(yùn)行時(shí)庫(kù):各種不同語(yǔ)言有不同的 安裝方法,,主流語(yǔ)言的包管理器都已支持,。
  • protoc,以及 grpc 插件和其它插件:采用 ProtoBuf 作為 IDL 時(shí),,對(duì) .proto 文件進(jìn)行編譯處理,。

官方文檔 寫的挺全面了。

類似其它 RPC 框架,,gRPC 的庫(kù)在服務(wù)端提供一個(gè) gRPC Server,,客戶端的庫(kù)是 gRPC Stub。典型的場(chǎng)景是客戶端發(fā)送請(qǐng)求,,同步或異步調(diào)用服務(wù)端的接口,。客戶端和服務(wù)端之間的通信協(xié)議是基于 HTTP2 的 gRPC 協(xié)議,,支持雙工的流式保序消息,,性能比較好,同時(shí)也很輕,。

采用 ProtoBuf 作為 IDL,,則需要定義 service 類型。生成客戶端和服務(wù)端代碼,。用戶自行實(shí)現(xiàn)服務(wù)端代碼中的調(diào)用接口,,并且利用客戶端代碼來(lái)發(fā)起請(qǐng)求到服務(wù)端。一個(gè)完整的例子可以參考 這里,。

以上面 proto 文件為例,,需要執(zhí)行時(shí)添加 grpc 的 plugin:

$ protoc --go_out=plugins=grpc:. hello.proto

生成服務(wù)端代碼

服務(wù)端相關(guān)代碼如下,主要定義了 HelloServiceServer 接口,,用戶可以自行編寫實(shí)現(xiàn)代碼,。

type HelloServiceServer interface {
        SayHello(context.Context, *HelloRequest) (*HelloResponse, error)
}

func RegisterHelloServiceServer(s *grpc.Server, srv HelloServiceServer) {
        s.RegisterService(&_HelloService_serviceDesc, srv)
}

用戶需要自行實(shí)現(xiàn)服務(wù)端接口,代碼如下,。

比較重要的,,創(chuàng)建并啟動(dòng)一個(gè) gRPC 服務(wù)的過程:

  • 創(chuàng)建監(jiān)聽套接字:lis, err := net.Listen("tcp", port)
  • 創(chuàng)建服務(wù)端:grpc.NewServer(),;
  • 注冊(cè)服務(wù):pb.RegisterHelloServiceServer(),;
  • 啟動(dòng)服務(wù)端:s.Serve(lis)
type server struct{}

// 這里實(shí)現(xiàn)服務(wù)端接口中的方法,。
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
    return &pb.HelloReply{Message: "Hello " + in.Name}, nil
}

// 創(chuàng)建并啟動(dòng)一個(gè) gRPC 服務(wù)的過程:創(chuàng)建監(jiān)聽套接字,、創(chuàng)建服務(wù)端、注冊(cè)服務(wù),、啟動(dòng)服務(wù)端,。
func main() {
    lis, err := net.Listen("tcp", port)
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    s := grpc.NewServer()
    pb.RegisterHelloServiceServer(s, &server{})
    s.Serve(lis)
}

編譯并啟動(dòng)服務(wù)端。

生成客戶端代碼

生成的 go 文件中客戶端相關(guān)代碼如下,主要和實(shí)現(xiàn)了 HelloServiceClient 接口,。用戶可以通過 gRPC 來(lái)直接調(diào)用這個(gè)接口,。

type HelloServiceClient interface {
        SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloResponse, error)
}

type helloServiceClient struct {
        cc *grpc.ClientConn
}

func NewHelloServiceClient(cc *grpc.ClientConn) HelloServiceClient {
        return &helloServiceClient{cc}
}

func (c *helloServiceClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloResponse, error) {
        out := new(HelloResponse)
        err := grpc.Invoke(ctx, "/hello.HelloService/SayHello", in, out, c.cc, opts...)
        if err != nil {
                return nil, err
        }
        return out, nil
}

用戶直接調(diào)用接口方法:創(chuàng)建連接、創(chuàng)建客戶端,、調(diào)用接口。

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.NewHelloServiceClient(conn)

    // Contact the server and print out its response.
    name := defaultName
    if len(os.Args) > 1 {
        name = os.Args[1]
    }
    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)
}

編譯并啟動(dòng)客戶端,,查看到服務(wù)端返回的消息,。

轉(zhuǎn)載請(qǐng)注明:http://blog.csdn.net/yeasy/article/details/52190007

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多