在微服务中,服务间调用关系错综复杂,一个微服务往往依赖于多个其它微服务。如下图,当前应用的运行依赖于服务A、H、I、P这4个微服务:
如果此时服务I发生了故障,当前应用的部分业务因为依赖于服务I,因此会被阻塞。此时,其它不依赖于服务I的业务似乎不受影响:
但是,依赖服务I的业务请求被阻塞,用户不会得到响应,则服务器的这个线程不会释放,于是越来越多的用户请求到来,越来越多的线程会阻塞:
服务器支持的线程和并发数有限,请求一直阻塞,会导致服务器资源耗尽,从而导致所有其它服务都不可用,那么当前服务也就不可用了。
随着时间的推移,依赖于当前服务的其它服务最终也都会变的不可用,形成级联失败,雪崩就发生了。
解决雪崩问题,主要有以下四种方式:超时处理、仓壁模式(线程隔离)、断路器、流量控制。
超时处理即设定超时时间,请求超过一定时间没有响应就返回错误信息,不会无休止等待。
仓壁模式来源于船舱的设计:船舱都会被隔板分离为多个独立空间,当船体破损时,海水只会进入部分空间,将故障控制在一定范围内,避免整个船体都被淹没。
与此类似,仓壁模式是限定每个微服务能使用的线程数,避免耗尽整个服务器的资源,因此也叫线程隔离。
断路器模式是指由断路器统计访问某个服务的请求数量和异常比例,如果异常比例超出阈值则会熔断该业务,拦截访问该业务的一切请求。
流量控制即限制业务访问的QPS,避免服务因流量的突增而故障。
总的来说,雪崩问题就是微服务之间相互调用,因为调用链中的一个服务故障,引起整个链路都无法访问的情况。
超时处理、线程隔离、降级熔断是在部分服务故障时,将故障控制在一定范围,避免雪崩,是一种补救措施。
流量控制是对服务的保护,避免因瞬间高并发流量而导致服务故障,进而避免雪崩,是一种预防措施。
在SpringCloud中支持多种服务保护技术:
早期比较流行的是Hystrix框架,但目前国内实用最广泛的还是阿里巴巴的Sentinel框架。
Sentinel是阿里巴巴开源的一款微服务流量控制组件。官网地址:https://sentinelguard.io/zh-cn/index.html
Sentinel官方提供了UI控制台,方便用户对系统做限流设置。可以在GitHub上下载。
sentinel-dashboard-1.8.1.jar
上传至服务器,并运行java -jar sentinel-dashboard-1.8.1.jar
Sentinel的默认端口、账户、密码如下:
如果要修改默认配置,可以通过添加参数的方式,例如修改端口:
java -Dserver.port=8090 -jar sentinel-dashboard-1.8.1.jar
http://192.168.245.130:8080
,输入账号密码,进入Sentinel控制台登录后,发现一片空白,什么都没有,这是因为还没有与微服务整合,但Sentinel已经安装完成了。
项目启动后,eureka中注册了一个sd-user-service微服务:
<!--sentinel-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
spring:
cloud:
sentinel:
transport:
dashboard: http://192.168.245.130:8080/
…
本节完,更多内容请查阅分类专栏:微服务学习笔记
感兴趣的读者还可以查阅我的另外几个专栏: