如何做到可靠的RPC
-
RPC可能会遇到什么故障?
- 包丢失、断网、服务器太慢、服务器崩溃(crash)
-
客户端没有收到回复,就可以认为是出错了
- 但是它无法区分到底服务器执行了命令没有。
- 可能服务器没有见到请求
- 可能服务器没有执行请求就崩溃了
- 可能服务器执行完请求,还没有来得及发回复就崩溃了。
-
没有收到回复的时候,RPC可以选择实现这几种语义:
- 不重发(Go RPC)
- 尽最大努力"best effort":简单地重试几次。服务器端会收到重复请求。
- 最多一次(at most once):服务器端记录并分辨重复请求。
- 恰好一次(exactly once):比较复杂!
“best effort”
-
最简单的处理办法是: “best effort”(尽最大努力)
- Call() 等待答复,等一段时间
- 如果超时了,就重新发送
- 如此反复几次
- 还是没用,就放弃并返回error
- 附注:ZeroMQ的手册里面,给这个再普通不过的方法起了个很神秘的名字:
Lazy Pirate Client
。
-
“尽最大努力”有些时候是不对的。服务器有会收到重复的请求。
- 比如:客户端执行
Put("k&
- 比如:客户端执行