快速开始
安装
首先,你需要安装rpcx:
go get -u -v github.com/smallnest/rpcx/...
该命令只安装rpcx的基本特性。如果你想安装etcd,你应该添加etcd
标签:
go get -u -v -tags "etcd" github.com/smallnest/rpcx/...
如果你想使用quic
,你还应该添加quic
标签:
go get -u -v -tags "quic etcd" github.com/smallnest/rpcx/...
我推荐你安装所有的组件尽管你可能目前用不上它们:
go get -u -v -tags "reuseport quic kcp zookeeper etcd consul ping" github.com/smallnest/rpcx/...
标签含义:
- quic:支持quic传输
- kcp:支持kcp传输
- zookeeper:支持zookeeper注册
- etcd:支持etcd之策
- consul:支持consul注册
- ping:支持网络质量负载均衡
- reuseport:支持reuseport
实现服务
你可以编写你自己的服务,就像编写一个普通的Go结构体:
import "context"
type Args struct {
A int
B int
}
type Reply struct {
C int
}
type Arith int
func (t *Arith) Mul(ctx context.Context, args *Args, reply *Reply) error {
reply.C = args.A * args.B
return nil
}
Arith
是一个Go类型,它有一个Mul
方法。Mul
方法的第一个参数是context.Context
。Mul
方法的第二个参数是args
。它包含请求数据:A
和B
。Mul方法的第三个参数是reply
。它是一个指向Reply
类型的指针。Mul
方法返回一个错误(可以是nil
)。Mul
使用A*B
的结果设置Relay.C。
现在你已经定义了一个Arich服务并且实现了它的Mul方法。我们会在之后的步骤里介绍如何把它暴露给服务器以及客户端如何调用它。
实现服务器
你可以通过三行代码实现以上服务:
s := server.NewServer()
s.RegisterName("Arith", new(Arith), "")
s.Serve("tcp", ":8972")
你可以使用Arith
作为名字注册你自己的服务。
你可以通过以下方式注册服务:
s.Register(new(example.Arith), "")
它使用服务类型名字作为服务名
实现客户端
// #1
d := client.NewPeer2PeerDiscovery("tcp@"+*addr, "")
// #2
xclient := client.NewXClient("Arith", client.Failtry, client.RandomSelect, d, client.DefaultOption)
defer xclient.Close()
// #3
args := &example.Args{
A: 10,
B: 20,
}
// #4
reply := &example.Reply{}
// #5
err := xclient.Call(context.Background(), "Mul", args, reply)
if err != nil {
log.Fatalf("failed to call: %v", err)
}
log.Printf("%d * %d = %d", args.A, args.B, reply.C)
#1
定义一个服务发现实现。在这个例子里面我们使用最简单的发现机制:Peer2PeerDiscovery。客户端通过链接服务发现获取服务器地址,然后直接连到服务器。
#2
创建一个XClient
,传递FailMode
,SelectMode
和默认选项。FailMode
指明客户端如何处理调用错误:重试、快速返回、或者重试其他的服务器?SelectMode
指明客户端在一个服务由多个服务器的时候如何选择服务器。
#3
定义一个请求:我们希望获取10*20
的值。当然我们知道结果肯定是200
,但是我们想看看服务器响应的是不是200
。
#4
定义结果对象,它是一个零值,实际上rpcx
可以使用它获取到结果的类型然后解码结果给它。
#5
调用远程服务,同步获取结果
异步调用服务
你可以异步调用服务:
d := client.NewPeer2PeerDiscovery("tcp@"+*addr2, "")
xclient := client.NewXClient("Arith", client.Failtry, client.RandomSelect, d, client.DefaultOption)
defer xclient.Close()
args := &example.Args{
A: 10,
B: 20,
}
reply := &example.Reply{}
call, err := xclient.Go(context.Background(), "Mul", args, reply, nil)
if err != nil {
log.Fatalf("failed to call: %v", err)
}
replyCall := <-call.Done
if replyCall.Error != nil {
log.Fatalf("failed to call: %v", replyCall.Error)
} else {
log.Printf("%d * %d = %d", args.A, args.B, reply.C)
}
你必须使用xclient.Go替换xclient.Call,它会返回一个通道,你可以从这个通道读取结果。