tinyrpc 是基于 protocol buffer 协议的高性能RPC框架. 它基于标准库 net/rpc
扩展而来,并且支持多种压缩格式 (gzip
, snappy
, zlib
)。
-
首先安装
protoc
生成器 :http://github.com/google/protobuf/releases -
安装
protoc-gen-go
和protoc-gen-tinyrpc
插件:
go install github.com/golang/protobuf/protoc-gen-go
go install github.com/zehuamama/tinyrpc/protoc-gen-tinyrpc
首先, 创建一个 demo
项目:
go mod init demo
创建 protocol buffer 文件 arith.proto
:
syntax = "proto3";
package message;
option go_package="/message";
// ArithService Defining Computational Digital Services
service ArithService {
// Add addition
rpc Add(ArithRequest) returns (ArithResponse);
// Sub subtraction
rpc Sub(ArithRequest) returns (ArithResponse);
// Mul multiplication
rpc Mul(ArithRequest) returns (ArithResponse);
// Div division
rpc Div(ArithRequest) returns (ArithResponse);
}
message ArithRequest {
int32 a = 1;
int32 b = 2;
}
message ArithResponse {
int32 c = 1;
}
这里定义了一个算数运算服务,我们使用 protoc
工具来生成代码:
protoc --tinyrpc_out=. arith.proto --go_out=. arith.proto
此时,在message
目录下会生成两个Go语言文件: arith.pb.go
and arith.svr.go
arith.svr.go
的代码如下:
// Code generated by protoc-gen-tinyrpc.
package message
// ArithService Defining Computational Digital Services
type ArithService struct{}
// Add addition
func (this *ArithService) Add(args *ArithRequest, reply *ArithResponse) error {
// define your service ...
return nil
}
// Sub subtraction
func (this *ArithService) Sub(args *ArithRequest, reply *ArithResponse) error {
// define your service ...
return nil
}
// Mul multiplication
func (this *ArithService) Mul(args *ArithRequest, reply *ArithResponse) error {
// define your service ...
return nil
}
// Div division
func (this *ArithService) Div(args *ArithRequest, reply *ArithResponse) error {
// define your service ...
return nil
}
最后,可以开始定义服务。
创建一个tinyrpc
服务端, 代码如下:
package main
import (
"demo/message"
"log"
"net"
"github.com/zehuamama/tinyrpc"
)
func main() {
lis, err := net.Listen("tcp", ":8082")
if err != nil {
log.Fatal(err)
}
server := tinyrpc.NewServer()
server.RegisterName("ArithService", new(message.ArithService))
server.Serve(lis)
}
我们创建一个tinyrpc
客户端并且同步调用 Add
函数:
conn, err := net.Dial("tcp", ":8082")
if err != nil {
log.Fatal(err)
}
defer conn.Close()
client := tinyrpc.NewClient(conn)
resq := message.ArithRequest{A: 20, B: 5}
resp := message.ArithResponse{}
err = client.Call("ArithService.Add", &resq, &resp)
你也可以异步调用它,AsyncCall方法会返回一个*rpc.Call
类型的通道:
result := client.AsyncCall("ArithService.Add", &resq, &resp)
select {
case call := <-result:
log.Printf("Arith.Add(%v, %v): %v ,Error: %v", resq.A, resq.B, resp.C, call.Error)
case <-time.After(100 * time.Microsecond):
log.Fatal("time out")
}
当然了,你也可以压缩编码,tinyrpc 目前支持的压缩格式有: gzip
, snappy
, zlib
。
import "github.com/zehuamama/tinyrpc/compressor"
// ...
client := tinyrpc.NewClient(conn, tinyrpc.WithCompress(compressor.Gzip))
resq := message.ArithRequest{A: 4, B: 15}
resp := message.ArithResponse{}
err = client.Call("ArithService.Mul", &resq, &resp)