介紹
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標準設計。
應用場景
- 低延時、高可用的分佈式系統
- 使用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
運行結果