gRPC是一個高性能、通用的開源RPC框架,其由Google主要面向移動應用開發並基於HTTP/2協議標準而設計,基於ProtoBuf(Protocol Buffers)序列化協議開發,且支持衆多開發語言。gRPC提供了一種簡單的方法來精確地定義服務和爲iOS、Android和後臺支持服務自動生成可靠性很強的客戶端功能庫。客戶端充分利用高級流和鏈接功能,從而有助於節省帶寬、降低的TCP鏈接次數、節省CPU使用、和電池壽命。
1、普通帳號安裝protobuf
unzip protobuf-cpp-3.0.0-alpha-3.zip
cd protobuf-3.0.0-alpha-3/
./configure
make && sudo make install
go get -u github.com/golang/protobuf/protoc-gen-go #golang 插件
2、定義grpc.proto文件
syntax = "proto3"; //protobuf3協議
package inf;
//請求
message UserRq {
int32 id = 1;
}
//響應
message UserRp {
string name = 1;
}
//服務
service Data {
rpc GetUser(UserRq) returns (UserRp);
}
然後編譯
cd ~/src/inf
protoc --go_out=plugins=grpc:. grpc.proto
3、get 所引用的包
go get -u google.golang.org/grpc
由於牆的原因,我們一些依賴的包文件可以通過下面方式下載到:
在 github 可以找到源碼,下載後複製到對應目錄即可的:
google.golang.org/grpc 對應的代碼地址在: https://github.com/grpc/grpc-go
google.golang.org/cloud/compute/metadata 對應的代碼地址在: https://github.com/GoogleCloudPlatform/gcloud-golang 不再需要
golang.org/x/oauth2 對應的代碼地址在: https://github.com/golang/oauth2
golang.org/x/net/context 對應的代碼地址在: https://github.com/golang/net
這些包的源碼也可以通過 http://gopm.io/ 或者 http://golangtc.com/download/package 進行下載.
4、服務端代碼
// grpc project main.go
package main
import (
"inf"
"log"
"net"
"runtime"
"strconv"
"golang.org/x/net/context"
"google.golang.org/grpc"
)
const (
port = "41005"
)
type Data struct{}
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
//起服務
lis, err := net.Listen("tcp", ":"+port)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
inf.RegisterDataServer(s, &Data{})
s.Serve(lis)
log.Println("grpc server in: %s", port)
}
// 定義方法
func (t *Data) GetUser(ctx context.Context, request *inf.UserRq) (response *inf.UserRp, err error) {
response = &inf.UserRp{
Name: strconv.Itoa(int(request.Id)) + ":test",
}
return response, err
}
5、客戶端代碼
package main
import (
"inf"
"log"
"runtime"
"strconv"
"strings"
"sync"
"time"
"math/rand"
"golang.org/x/net/context"
"google.golang.org/grpc"
)
var (
wg sync.WaitGroup
)
const (
networkType = "tcp"
server = "127.0.0.1"
port = "41005"
parallel = 50 //連接並行度
times = 100000 //每連接請求次數
)
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
currTime := time.Now()
//並行請求
for i := 0; i < int(parallel); i++ {
wg.Add(1)
go func() {
defer wg.Done()
exe()
}()
}
wg.Wait()
log.Printf("time taken: %.2f ", time.Now().Sub(currTime).Seconds())
}
func exe() {
//建立連接
conn, _ := grpc.Dial(server + ":" + port)
defer conn.Close()
client := inf.NewDataClient(conn)
for i := 0; i < int(times); i++ {
getUser(client)
}
}
func getUser(client inf.DataClient) {
var request inf.UserRq
r := rand.Intn(parallel)
request.Id = int32(r)
response, _ := client.GetUser(context.Background(), &request) //調用遠程方法
//判斷返回結果是否正確
if id, _ := strconv.Atoi(strings.Split(response.Name, ":")[0]); id != r {
log.Printf("response error %#v", response)
}
}
引用
http://www.infoq.com/cn/news/2015/03/grpc-google-http2-protobuf
https://github.com/google/protobuf
https://github.com/golang/protobuf
http://studygolang.com/articles/3192