Hunter的博客

可靠性设计之服务故障隔离

案例场景

程序首先做黑名单规则校验,将命中规则的黑名单数据先写入DB,后邮件发送给相关业务人员

一般步骤

在做完黑名单规则校验之后,可以直接返回客户端命中结果,后面的写入DB和邮件发送操作可以放到线程池中异步进行。
那么是不是两个操作都放到一个线程池中进行操作呢?当然不是,至于为什么,看下面分析

案例分析

从业务场景分析得出,写入DB操作明显是主要业务,邮件发送是次要业务,所以从服务优先级考虑首先要保证的是主要业务的可用,然后再保证次要业务的可用。

再回到上面的问题,为什么不能将这两个操作放到同一个线程池中进行操作。

假如这两个操作从同一个池中取线程,第一个写入DB顺利完成,第二个发送邮件由于网络原因(如连接超时等)导致发送失败,这里的失败的结果可能导致线程夯住;最坏的结果会是随着服务请求的增多,因为发送邮件这个操作导致线程池资源耗尽,使得写入DB这个操作无法分配到可以用线程资源,进入队列中等待,这样可能会出现等待超时,导致写入DB操作被丢弃,从而导致DB数据丢失;这样因为一个次要业务不可用故障级联主要业务不可用是程序设计中不允许的。
这里我们可以将写入DB操作分配到一个线程池,发送邮件操作分配到另外一个线程池,这样即使发送邮件操作失败导致线程池不可用,也不会影响到写入DB操作这个功能;

总结

上面是关于服务故障隔离的一点点思路,也是我们能在代码层面进行实施的东西;其实关于服务故障隔离远不止这么简单,这里只是提供一点思路,就是从我们的业务进行分析,哪些是核心业务哪些是非核心业务,我们要做的就是优先保证核心业务的高可用,其次再是保证非核心业务的可用。