Spring Cloud微服务架构中的服务保护是非常重要的,它能够确保系统的稳定性和可用性,特别是在面对突发流量或者服务异常的情况下。常用的微服务保护方案包括但不限于以下几个方面:
- 熔断 (Circuit Breaker) 熔断机制用于在服务出现问题时快速失败,避免调用链路中的服务相互等待,导致整体系统响应变慢甚至不可用。
如何快速失败(fast fail)呢?当服务的错误率达到一定程度时,断路器(相当于保险丝)会打开,直接返回错误而不是尝试调用服务。一段时间后,断路器会处于半开状态尝试调用服务,如果服务恢复正常,则关闭断路器。
【知识拓展】
AI:fast fail和safe fail区别
答:
Fast Fail(快速失败):旨在快速暴露问题,防止错误扩散或导致更严重的后果,如医疗、金融场景。缺点是:导致系统中断,影响用户体验【直接抛异常】
Safe Fail(安全失败):旨在最大程度保证系统可用和安全性,如在线服务、云计算平台。缺点是:可能导致问题被掩盖,增加修复难度。【try-catch,返回一个默认值(即降级)】
由断路器统计业务执行的异常比例,如果超出阈值则会熔断该业务,拦截访问该业务的一切请求。
- 降级 (Degradation) 断路器会统计访问某个服务的请求数量,统计服务提供方的异常比例,当比例过高表明该接口会影响到其它服务,应该拒绝调用该接口,而是直接走降级逻辑。
降级逻辑 即提供一个简化的响应或者默认的响应来代替正常的服务调用。这样可以保证核心业务不受影响,非核心业务暂时被限制或关闭。
熔断后,接口还通吗?
不通,直接异常
降级后,接口还通吗?
通,但返回的是降级逻辑,即类似一个默认值,故业务逻辑不一定闭环,后续还需要人工补偿
- 超时 (Timeout) 设置合理的超时时间可以避免长时间等待响应导致的问题。当请求超时时,可以选择快速失败并返回错误信息,或者重试等策略。
常见的远程调用框架,都设置了超时机制。
AI:目前Http、Dubbo、WebService都有超时机制吗?
答:是的,HTTP、Dubbo 和 WebService 都支持超时机制,但它们的实现方式和配置方法有所不同
HTTP:连接超时、读取超时
Dubbo:服务调用超时(默认3s),超时后自动重试2次
WebService:连接超时、读取超时
- 线程隔离 (Thread Isolation) 线程隔离是指为每个服务分配独立的线程池,这样即使某个服务出现问题也不会影响到其他服务。
线程隔离的思想来自轮船的舱壁模式:
轮船的船舱会被隔板分割为N个相互隔离的密闭舱,假如轮船触礁进水,只有损坏的部分密闭舱会进水,而其他舱由于相互隔离,并不会进水。这样就把进水控制在部分船体,避免了整个船舱进水而沉没。
为了避免某个接口故障或压力过大导致整个服务不可用,我们可以限定每个接口可以使用的资源范围,也就是将其“隔离”起来。
如图所示,我们给查询购物车业务限定可用线程数量上限为20,这样即便查询购物车的请求因为查询商品服务而出现故障,也不会导致服务器的线程资源被耗尽,不会影响到其它接口。
- 限流 (Rate Limiting) 限流是最常见的服务保护措施之一,其目的是为了防止服务因为过大的流量而崩溃。
对于某些关键资源或者参数的访问,可以采取特殊的限流措施来防止这些热点成为瓶颈。
限流往往会有一个限流器,数量高低起伏的并发请求曲线,经过限流器就变的非常平稳。这就像是水电站的大坝,起到蓄水的作用,可以通过开关控制水流出的大小,让下游水流始终维持在一个平稳的量。
可以通过以下几种方式进行限流(有兴趣的可以看看下面两种实现方案,前期可以仅做了解):
- 基于令牌桶算法:允许一定数量的请求通过,超出则拒绝或排队等待。
- 基于滑动窗口:在一段时间内对请求进行计数,超过阈值则触发限流。