常见容错机制:failover ,failsafe,failfase ,failback,forking,来源于阿里的定义。
Failover 失败自动切换
当出现失败,重试其它服务器,通常用于读操作(推荐使用)。 重试会带来更长延迟。
Failfast 快速失败
只发起一次调用,失败立即报错,通常用于非幂等性的写操作。 如果有机器正在重启,可能会出现调用失败 。
Failsafe 失败安全
出现异常时,直接忽略,通常用于写入审计日志等操作。 调用信息丢失 可用于生产环境 Monitor。
Failback 失败自动恢复
后台记录失败请求,定时重发。通常用于消息通知操作 不可靠,重启丢失。 可用于生产环境 Registry。
Forking 并行调用多个服务器
只要一个成功即返回,通常用于实时性要求较高的读操作。 需要浪费更多服务资源 。
Broadcast
广播调用,所有提供逐个调用,任意一台报错则报错。通常用于更新提供方本地状态 速度慢,任意一台报错则报错 。
为什么需要做服务隔离与熔断
由于微服务间通过RPC来进行数据交换,所以我们可以做一个假设:在IO型服务中,假设服务A依赖服务B和服务C,而B服务和C服务有可能继续依赖其他的服务, 继续下去会使得调用链路过长,技术上称1->N扇出。如果在A的链路上某个或几个被调用的子服务不可用或延迟较高,则会导致调用A服务的请求被堵住,堵住的请求会消耗占用掉系统的线程、io等资源,当该类请求越来越多,占用的计算机资源越来越多的时候,会导致系统瓶颈出现,造成其他的请求同样不可用,最终导致业务系统崩溃,又称:雪崩效应。
雪崩的处理方式:
熔断机制、隔离模式、限流模式
熔断设计
在熔断的设计主要参考了hystrix的做法。其中最重要的是三个模块:熔断请求判断算法、熔断恢复机制、熔断报警
(1)熔断请求判断机制算法:使用无锁循环队列计数,每个熔断器默认维护10个bucket,每1秒一个bucket,每个blucket记录请求的成功、失败、超时、拒绝的状态,默认错误超过50%且10秒内超过20个请求进行中断拦截。
(2)熔断恢复:对于被熔断的请求,每隔5s允许部分请求通过,若请求都是健康的(RT<250ms)则对请求健康恢复。
(3)熔断报警:对于熔断的请求打日志,异常请求超过某些设定则报警
隔离设计
隔离的方式一般使用两种
(1)线程池隔离模式:使用一个线程池来存储当前的请求,线程池对请求作处理,设置任务返回处理超时时间,堆积的请求堆积入线程池队列。这种方式需要为每个依赖的服务申请线程池,有一定的资源消耗,好处是可以应对突发流量(流量洪峰来临时,处理不完可将数据存储到线程池队里慢慢处理)
(2)信号量隔离模式:使用一个原子计数器(或信号量)来记录当前有多少个线程在运行,请求来先判断计数器的数值,若超过设置的最大线程个数则丢弃改类型的新请求,若不超过则执行计数操作请求来计数器+1,请求返回计数器-1。这种方式是严格的控制线程且立即返回模式,无法应对突发流量(流量洪峰来临时,处理的线程超过数量,其他的请求会直接返回,不继续去请求依赖的服务)
超时机制设计
超时分两种,一种是请求的等待超时,一种是请求运行超时。
等待超时:在任务入队列时设置任务入队列时间,并判断队头的任务入队列时间是否大于超时时间,超过则丢弃任务。
运行超时:直接可使用线程池提供的get方法