這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
關於RPC(Remote Procedure Call)的定義,可以參考這兩篇文章:Remote procedure call和Remote Procedure Call (RPC)。簡單來講,RPC指的就是一個進程(client)發起一個函數調用,但是實際用來執行這個函數調用是另一個進程(server)。這個函數調用會阻塞在那裡,直到收到響應。Server進程可以與client進程可以位於同一台機器也可以是不同機器。Client和server都有一個stub模組,client的stub負責發送request,並處理server返回的response;而server的stub則負責處理client發送的request,並返回response。 通常,我們使用Interface Description Language來定義RPC的訊息格式。
gRPC是google實現的RPC,其預設使用protocol buffers,一個使用gRPC的例子如下(圖出自Getting started):
以Go語言為例,搭建gPRC環境包括下列幾步:
(1)安裝gRPC runtime:
go get google.golang.org/grpc
(2)安裝protocol buffers支援(包含compiler和runtime):從protocol buffers官網下載最新的源碼包,解壓縮:
./configuremakemake checkmake installldconfig
(3)安裝Go protoc plugin:
go get -a github.com/golang/protobuf/protoc-gen-go
參考gRPC提供的例子,下載helloworld.proto檔案,然後在目前的目錄執行“protoc --go_out=plugins=grpc:. *.proto”就會在目前的目錄下產生helloworld.pb.go檔案。對於client來講,發送request的函數已產生好,只需直接傳入request內容以及option即可:
type GreeterClient interface { // Sends a greeting SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error)}type greeterClient struct { cc *grpc.ClientConn}func NewGreeterClient(cc *grpc.ClientConn) GreeterClient { return &greeterClient{cc}}func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) { out := new(HelloReply) err := grpc.Invoke(ctx, "/helloworld.Greeter/SayHello", in, out, c.cc, opts...) if err != nil { return nil, err } return out, nil}
對於server,定義好了interface,需要自己實現滿足這個interface的結構體:
// Server API for Greeter servicetype GreeterServer interface { // Sends a greeting SayHello(context.Context, *HelloRequest) (*HelloReply, error)}
可以看出,SayHello()函數只要實現如何構造response即可,其它如何傳輸訊息等等,均不用管。
為了熟悉這個流程,我自己做了一遍,代碼在這裡:https://github.com/NanXiao/helloworld。