有个分布式下的业务场景大概是这样子:节点收到客户端请求后,将消息发到多个副本节点,待收到若干副本回复以后,再返回给客户端。
肯定不能对到来的请求一个个串行服务,对吧,吞吐不可接受。于是来一个请求后节点都会记下session id,并行地执行很多客户端的请求,等收到足够多副本节点的回复以后回调一个函数,根据session来回复客户端。
这个业务还有个特点,只有leader节点会服务客户,副本节点不会,leader可能会切换。
于是一个bug出现了:有时候客户端永远得不到回复。为什么呢?发个请求到leader,处理请求期间leader切换了,新的leader上并没有那些session信息。
大概你会说,可以这么做呀:原leader在丢失身份的时候,需要返回错误给客户端,告诉它自已服务不了这次请求了。
好吧,我承认我简化场景了。实际是这样的,原leader中排队中的请求,它们可能会执行,也可能不会。假设失去身份之前消息已经同步到了新的leader节点了,消息就会执行。
郁闷的是,不能简单地返回客户端:不知道执行没有。因为这样子返回,客户端可能重试,而重试不是幂等的操作,会破坏业务。
这个业务还有一个蛋疼的,它要处理的某一种请求正好就是切换leader!你大概猜到了,明显又是大坑。执行了这个请求,那些还在排队中的请求要怎么搞?
额...很委屈的说,已经是简化很多后的场景了!
Read full article from 异步烧脑业务场景
No comments:
Post a Comment