1、什么是微服务保护
微服务保护是指在微服务架构中采取的一系列措施,以确保各个服务的稳定性、可靠性和安全性。微服务是一种将应用程序作为一套小服务开发的方法,每个服务运行在其独立的进程中,并通常围绕特定的业务能力进行构建。微服务保护的目标是防止单个服务的故障影响到整个系统
2、Sentinel的使用
方案的使用要基于SpringCloudAlibaba的Sentinel组件
2.1、下载SentinelJAR包放在无中文路径无特殊字符的目录cmd进入命令提示框输入命令:
java -Dserver.port=8090 -Dcsp.sentinel.dashboard.server=localhost:8090 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
2.2、启动成功访问http://localhost:8090/ 网址输入默认账号密码Sentinel,进入主界面
2.3、 微服务模块引入依赖
<!--sentinel服务保护--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency>
2.4、 在yaml文件配置Sentinel配置项,用于服务发现
spring:cloud:sentinel:transport:dashboard: localhost:8090http-method-specify: true # 开启请求方式前缀
2.5、 测试,访问该模块的任意网址后,Sentinel会自动检测该模块的所有请求
3、微服务保护的方案
3.1、流量控制:
限流:限制每个服务的请求量,防止过载。
流量整形:调整流量的分布,避免服务因瞬时高峰流量而崩溃。
服务故障最重要原因,就是并发太高!解决了这个问题,就能避免大部分故障。当然,接口的并发不是一直很高,而是突发的。因此请求限流,就是限制或控制接口访问的并发流量,避免服务因流量激增而出现故障
3.1.1、启用流量控制
3.1.2、设置QPS为6,意思是该接口每秒可以接受6个请求
测试,我们在jmeter上模拟前端在10秒中发送1000个请求,如图QPS为6左右
3.2、服务隔离:
服务独立性:确保一个服务的故障不会影响到其他服务。
服务隔离:通过隔离技术(如容器化)来运行服务,减少服务间的相互影响。
3.2.1、修改cart-service模块的yaml文件添加以下内容,来开启Fegin的Sentinel功能
feign:sentinel:enabled: true # 开启feign对sentinel的支持
这样该模块所依赖的openFegin客户端接口也会被监控到,并会生成在该簇点的下级链路
3.2.2、配置线程隔离
并发线程数限制,也就是说这个查询功能最多使用5个线程,而不是5QPS。如果查询商品的接口每秒处理2个请求,则5个线程的实际QPS在10左右,而超出的请求自然会被拒绝.
这就证明线程隔离起到了作用,尽管查询购物车这个接口并发很高,但是它能使用的线程资源被限制了,因此不会影响到其它接口。
就是当大量请求到某一个服务模块时,在第一层对流量进行限制,进行了第一次降低并发量,但是这些请求到达该服务时,访问的接口众多,往往一个接口的耗时非常慢,就会拖垮其他请求,导致响应时间过长,这是我们就要对某些接口进行线程隔离,只允许固定数量的线程去访问该接口,降低一个接口拖垮整个请求的现象。
3.3、服务降级:
触发限流或熔断后的请求不一定要直接报错,也可以返回一些默认数据或者友好提示,用户体验会更好。
3.3.1、创建降级处理类
在hm-api模块中给ItemClient
定义降级处理类,实现FallbackFactory
package com.hmall.api.client.fallback;import com.hmall.api.client.ItemClient;
import com.hmall.api.dto.ItemDTO;
import com.hmall.api.dto.OrderDetailDTO;
import com.hmall.common.exception.BizIllegalException;
import com.hmall.common.utils.CollUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;import java.util.Collection;
import java.util.List;@Slf4j
public class ItemClientFallback implements FallbackFactory<ItemClient> {@Overridepublic ItemClient create(Throwable cause) {return new ItemClient() {@Overridepublic List<ItemDTO> queryItemByIds(Collection<Long> ids) {log.error("远程调用ItemClient#queryItemByIds方法出现异常,参数:{}", ids, cause);// 查询购物车允许失败,查询失败,返回空集合return CollUtils.emptyList();}@Overridepublic void deductStock(List<OrderDetailDTO> items) {// 库存扣减业务需要触发事务回滚,查询失败,抛出异常throw new BizIllegalException(cause);}};}
}
3.3.2 、将该接口注册为Bean
在client接口来使用Bean对象
3.3.3、测试
使用jmter测试发现不再报异常,拒绝的QPS而是走了服务降级策略
这些方案或多或少都会导致服务的体验上略有下降,比如请求限流,降低了并发上限;线程隔离,降低了可用资源数量;服务熔断,降低了服务的完整度,部分服务变的不可用或弱可用。因此这些方案都属于服务降级的方案。但通过这些方案,服务的健壮性得到了提升
3.4、服务熔断:
快速失败:当服务调用失败次数超过阈值时,快速返回失败结果,避免系统资源浪费。
慢调用比例熔断:当服务调用的慢调用比例超过阈值时,触发熔断,避免系统资源耗尽。
熔断服务
Sentinel中的断路器不仅可以统计某个接口的慢请求比例,还可以统计异常请求比例。当这些比例超出阈值时,就会熔断该接口,即拦截访问该接口的一切请求,降级处理;当该接口恢复正常时,再放行对于该接口的请求
状态机包括三个状态:
-
closed:关闭状态,断路器放行所有请求,并开始统计异常比例、慢请求比例。超过阈值则切换到open状态
-
open:打开状态,服务调用被熔断,访问被熔断服务的请求会被拒绝,快速失败,直接走降级逻辑。Open状态持续一段时间后会进入half-open状态
-
half-open:半开状态,放行一次请求,根据执行结果来判断接下来的操作。
-
请求成功:则切换到closed状态
-
请求失败:则切换到open状态
-
3.4.1、设置熔断参数
这种是按照慢调用比例来做熔断,上述配置的含义是:
-
RT超过200毫秒的请求调用就是慢调用
-
统计最近1000ms内的最少5次请求,如果慢调用比例不低于0.5,则触发熔断
-
熔断持续时长20s
3.4.2、测试
使用jmter来测试发现前一半的请求都可以正常访问,当熔断器开始工作时,所有的请求都无法到达服务器