市场上很多分布式计算系统声称自己无惧宕机,一个节点挂不会影响系统正常服务。
这句话实际要表达的意思是:对于点查询(TP查询),宕机后一条查询失败,后继查询会路由到新机器执行。总体上看,对系统服务无影响。
也就是说,声称无惧宕机的人,脑袋里装的图景是整个系统,而不是一条查询。
当我们看一条查询的时候,它可能是惧怕宕机的。甚至,宕机后这条查询会卡住很久。为什么呢?因为一个请求通过 RPC 执行时,执行到一半宕机,RPC 发起者可能无法立即感知到。那么发起者会一直等,等到超时。
对于一个涉及到多机查询的 Query,它会发出多个 RPC,其中一个宕机,可能就会阻塞整个 Query。要真正让用户有更好的体验,需要让这个 Query 立即失败。这就提出一个要求:
RPC 如何立即感知宕机?
对于同步、异步 RPC,要求 RPC 底层做两件事:
- 感知 TCP 连接是否被中断
- QoS 探测,及时感知对端假死
一旦感知到异常,立即通知 RPC 调用端异常事件。
对于逻辑连接,会复杂一些。所以“逻辑连接” 是说调用端先通过 RPC 启动执行端;执行端通过另一个 RPC 将结果返回给调用端。这时一旦执行端异常,调用端无法直接通过 RPC 感知到问题。对于这种情况,我们需要有一个全系统的诊断机制,一旦发现有机器异常,能将这个异常状态暴露给调用者查询。调用者的逻辑可能是这样:
send_request();
while (wait_more_result) {
check_result();
for_every_10_seconds_without_any_result {
if (any_server_down) {
wait_more_result = false;
}
}
}
只有建立健全的检测机制,才能及时感知到分布式系统中的异常,尽可能早地退出异常状态,让用户有可接受的异常体验。