一. Sentinel
官网:sentinelguard.io/zh-cn/ 下载Sentinel: github.com/alibaba/Sen...
导入依赖
java
<!--sentinel-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
修改application.yaml文件
java
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8090
cmd启动Sentinel的jar包:java -Dserver.port=8090 -Dcsp.sentinel.dashboard.server=localhost:8090 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar 输入:http://localhost:8090 账号和密码,默认都是:sentinel

二. 请求限流
请求限流,就是限制或控制接口访问的并发流量,避免服务因流量激增而出现故障。 请求限流往往会有一个限流器 ,数量高低起伏的并发请求曲线,经过限流器就变的非常平稳。这就像是水电站的大坝,起到蓄水的作用,可以通过开关控制水流出的大小,让下游水流始终维持在一个平稳的量。

添加限流

给予每秒10次的请求次数

可以看到大概6次通过,4次拒绝

三. 线程隔离
限流可以降低服务器压力,尽量减少因并发流量引起的服务故障的概率,但并不能完全避免服务故障。一旦某个服务出现故障,我们必须隔离对这个服务的调用,避免发生雪崩。
如图所示,我们给查询购物车业务限定可用线程数量上限为20,这样即便查询购物车的请求因为查询商品服务而出现故障,也不会导致服务器的线程资源被耗尽,不会影响到其它接口。
添加线程数控制,也是点击流控

每秒钟100个线程请求

大概5个通过,95个失败

四. Fallback
修改cart-service模块的application.yml文件,开启Feign的sentinel功能:
java
feign:
sentinel:
enabled: true # 开启feign对sentinel的支持
给FeignClient编写失败后的降级逻辑有两种方式:
- 方式一:FallbackClass,无法对远程调用的异常做处理
- 方式二:FallbackFactory,可以对远程调用的异常做处理,我们一般选择这种方式。 在这里插入图片描述
在hm-api模块中给ItemClient定义降级处理类,实现FallbackFactory:
java
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.utils.CollUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import java.util.Collection;
import java.util.List;
public class ItemClientFallbackFactory implements FallbackFactory<ItemClient> {
private static final Logger log = LoggerFactory.getLogger(ItemClientFallbackFactory.class);
@Override
public ItemClient create(Throwable cause) {
return new ItemClient() {
@Override
public List<ItemDTO> queryItemsByIds(Collection<Long> itemIds) {
log.error("查询商品信息失败", cause);
return CollUtils.emptyList();
}
@Override
public void deductStock(List<OrderDetailDTO> items) {
log.error("扣减商品库存失败", cause);
throw new RuntimeException(cause);
}
};
}
}
在hm-api模块中的com.hmall.api.config.DefaultFeignConfig类中将ItemClientFallback注册为一个Bean:
java
@Bean
public ItemClientFallbackFactory itemClientFallbackFactory() {
return new ItemClientFallbackFactory();
}
在hm-api模块中的ItemClient接口中使用ItemClientFallbackFactory:
java
@FeignClient(value = "item-service",
configuration = DefaultFeignConfig.class,
fallbackFactory = ItemClientFallbackFactory.class)
public interface ItemClient {
@GetMapping("/items")
List<ItemDTO> queryItemsByIds(@RequestParam("ids") Collection<Long> itemIds);
@PutMapping("/items/stock/deduct")
public void deductStock(@RequestBody List<OrderDetailDTO> items);
}
发现被限流的请求不再报错,走了降级逻辑: 
五. 服务熔断
查询商品的RT较高(模拟的500ms),从而导致查询购物车的RT也变的很长。这样不仅拖慢了购物车服务,消耗了购物车服务的更多资源,而且用户体验也很差。 对于商品服务这种不太健康的接口,我们应该停止调用,直接走降级逻辑,避免影响到当前服务。也就是将商品查询接口熔断。当商品服务接口恢复正常后,再允许调用。这其实就是断路器的工作模式了。
状态机包括三个状态:
- closed:关闭状态,断路器放行所有请求,并开始统计异常比例、慢请求比例。超过阈值则切换到open状态
- open:打开状态,服务调用被熔断,访问被熔断服务的请求会被拒绝,快速失败,直接走降级逻辑。Open状态持续一段时间后会进入half-open状态
- half-open:半开状态,放行一次请求,根据执行结果来判断接下来的操作。
- 请求成功:则切换到closed状态
- 请求失败:则切换到open状态
在控制台通过点击簇点后的熔断按钮来配置熔断策略:

- RT超过200毫秒的请求调用就是慢调用
- 统计最近1000ms内的最少5次请求,如果慢调用比例不低于0.5,则触发熔断
- 熔断持续时长20s

在一开始一段时间是允许访问的,后来触发熔断后,查询商品服务的接口通过QPS直接为0,所有请求都被熔断了。而查询购物车的本身并没有受到影响。