业务复杂,做业务的产品更复杂。越复杂的业务产品,所依赖的外围系统可能就越多。假如突然有一天,依赖的外围系统挂掉了,少侠你是否给业务留了后路?
可能前面的话听上去有点晕,到底啥意思?来,举个栗子。
假如今天馒头去医院体检,需要经历的体检流程“1-2-3-4”如上图所示。但这里有个变态规则就是:必须按流程顺序完成1-4的所有环节,体检才算成功。(翻译过来就是说:每完成一步,1-4的应用系统会将数据返回给到体检系统,并触发体检系统向下一应用系统请求数据。当体检系统依次向4个应用系统分别请求数据成功后,则记为“体检成功”。如果一旦体检系统某次请求数据失败,体检系统则不会继续向下一应用系统请求数据,处于“体检进行中”的状态)
假如此时,血常规检查的仪器挂掉了,而down机时间又不确定。但因为变态的规则,导致馒头我只得停留在第2步“血常规检查”,体检因此无法继续进行下去。同时随着down机时间的延长和医院体检人数的增加,停留在第2步而无法继续进行下去的人越来越多,情绪上已处于失控状态;但此时院方又束手无策,因为这是体检系统写死的规则,不可更改。所以,此时此刻只有2种解决方案:要么告诉大家耐心等待,直至血常规检查的仪器恢复正常,要么告知大家该回家的回家,该上班的上班,改日再来医院体检。我相信如果少侠是体检的同学,那此时的内心早已是崩溃的…
大家发现没有,正是因为产品设计上没有考虑到异常流,因此导致在异常情况发生时埋下了这个天坑。由此可见,做产品留后路非常重要!
留后路,什么意思?
还是刚才的例子,假如我在设计体检系统的产品时,让技术同学写一串代码:“if 血常规检查系统down机所引起的数据请求失败,则直接进行下一应用系统的数据请求。”大家发现没有,此时体检系统就会直接跳过血常规数据的请求,来请求心电应用系统的数据。换言之,也就是说我可以不用作血常规检查直接进行心电图检查,到最后体检依然是成功的。可能唯一的问题就在于我拿到的体检报告中,血常规这一项是没有检查结果的。不过假如体检的同学不在乎,那这就不叫问题。
那其实刚刚所说的就叫异常降级策略。比如上述设计中,当我们的系统调用外围系统出现超时等报错情况下,可以让我们的系统吃掉异常的情况继续业务,这就是一种异常降级策略。当然了,一般来说是有3种不同程度的异常降级策略,但这些是需要视业务的重要性来决定究竟采取何种策略。
现在我们以医院的体检系统产品为例来解释一下上图的含义。在1-4的体检流程中,第一步非常重要,原因是在信息没有注册的情况下,这个体检是没有意义的,因为到头来不知道在为“谁”做体检。所以,由此可见“信息注册”的业务重要性相对其他环节要高,因此如果一旦系统请求信息注册的数据有问题,就默认拦截不要业务下去了。那这里的高风险又是什么意思?因为一旦拦截就不能继续业务,比如信息无法注册导致tmd我就不能体检了,医院的体检就不能搞起了(至少是在此时此刻和未来的一段时间内),所以对业务来说一定是高风险的。那像“打印体检报告”这一环节,业务上的重要性就低很多,因为此时此刻我不能打印体检报告,我照样可以在手机或pc上查看到体检报告的数据,再不济可以改日来医院打印体检报告。所以,如果体检报告的打印出现了问题,可以采取直接放行跳过的降级策略,最终是能够保证体检成功的,那这里所带来的业务风险就几乎为0了。
不过,大家有没有注意到无论采取何种异常降级策略,我们的系统每跑一次业务都是要去请求一次外围系统,来看看外围系统是否down机,如果down机就采取相应的异常降级策略,其实这样“每跑一次业务就去请求一次”的处理效率是很低的。
因此也就有了主动降级策略的概念,什么意思?就是我可以在后台配置一个开关来主动控制系统是否直接跳过向外围系统请求的过程。假设我已经监测到“信息注册”的系统down掉了,那我就可以直接推开关来命令体检系统在接下来的一段时间内不再去请求该外围系统,这样就大大提升了业务进行的效率,原因是我干掉了向down机系统进行不必要的请求询问的时间。
所以回到体检这件事,如果我是设计者,就会采取相应的异常降级策略和主动降级策略。第1步信息注册的异常降级策略是“默认拦截”,第2步、第3步的血常规检查和心电检查的异常降级策略是“日常拦截,紧急放行”,而第4步体检报告打印的异常降级策略就是“默认放行”。另外,我还会在后台做三个开关来对第2步、第3步、第4步实施主动降级策略。
这样的话,即便哪天业务君对馒头哭诉机器突然挂掉的悲伤故事时,馒头我依然可以微笑地看着业务君并温柔地对他说:“别怕,有我!你看,我给业务留了后路…”
哦对了,
我所说的,都是错的。