RPC in Go有某种缓存吗?

时间:2016-06-09 08:34:41

标签: go rpc

昨天我在使用RPC进行游戏时遇到了一些我无法理解的行为。

我编写了一个简单的RPC服务器,它在VM中运行,侦听连接并为斐波那契计算提供单一方法。 本地机器上的RPC客户端每秒向服务器询问fibonacci(n),其中n是(currentSecond * fixedMultiplicator),因此我可以产生至少稍微不同的负载。

因此,在for循环中,客户端将在60秒内请求60个不同的值,然后重新开始。 RPC拨号位于此循环之外,因此连接有点持久。

当我杀死服务器时,让我们说,10秒后,客户端将抛出一个错误,因为它无法向现在丢失的服务器发送任何内容。到目前为止,按计划工作。

现在让我想到的是:当我在61秒后终止服务器时,客户端会不断打印出正确的结果,但服务器丢失且无法回复请求。我甚至关闭了服务器的VM,因此服务器IP甚至不再在网络中了。 虽然有点有趣,但这种行为可能对实际应用程序有害(取决于您正在开发的内容)。

有什么想法吗?

// ############
// # RPC SERVER

err := rpc.Register(service.Object)
// errorcheck

rpc.HandleHTTP()
l, e := net.Listen("tcp", ":1301")
// errorcheck
go http.Serve(l, nil)


// ############
// # RPC CLIENT

client, err := rpc.DialHTTP("tcp", "192.168.2.111:1301")
// errorcheck

var divCall *rpc.Call

for {
    <-time.After(time.Duration(1 * time.Second)):

    n := time.Now().Second() * 90000000
    log.Debug("n=", n)

    args := &services.FibonacciArgs{N: n}
    var reply int
    divCall = client.Go("Fibonacci.Calculate", args, &reply, nil)

    go func() {
        replyCall := <-divCall.Done
        r := replyCall.Reply.(*int)
        log.Debug("reply: ", r)
    }()
}

答案

在Linux和Windows上运行代码后,我发现了不同的结果。 在Linux上,回复将始终是适当的零值(在我的情况下为0)。另一方面,在Windows上,回复似乎是缓存的。

要走的路是@cnicutar的提示。在RPC调用之后检查错误值并相应地处理内容。永远不要盲目相信这个回复。

1 个答案:

答案 0 :(得分:2)

您不会检查代码中的错误:

divCall = client.Go("Fibonacci.Calculate", args, &reply, nil)

go func() {
    replyCall := <-divCall.Done

    // -- Must check replyCall.Error here --.

    r := replyCall.Reply.(*int)
    log.Debug("reply: ", r)
}()

那就是说,我认为这种行为很奇怪,可能还有更多。