目录
2、访问http://localhost:8080,账号密码都是sentinel
一、雪崩问题
介绍:
解决方案:
1、超时处理
设定超时时间,请求超过一定时间没有响应就返回错误信息,不会无休止等待
2、舱壁模式
限定每个业务能使用的线程数,避免耗尽整个tomcat的资源,因此也叫线程隔离。
3、熔断降级
由断路器统计业务执行的异常比例,如果超出阈值则会熔断该业务,拦截访问该业务的一切请求。
4、流量控制
限制业务访问的QPS,避免服务因流量的突增而故障。
总结:
二、Sentinel与Hystrix的对比
三、认识Sentinel(微服务与控制台进行整合)
Sentinel是阿里巴巴开源的一款微服务流量控制组件。
官网地址:home | Sentinel
特点:
丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
完善的SPI扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
1、启动sentinel
java -jar sentinel-dashboard-1.8.1.jar
2、访问http://localhost:8080,账号密码都是sentinel
3、修改端口
4、修改项目pom文件
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
5、修改yml文件
cloud:
sentinel:
transport:
dashboard: localhost:8080
6、打开nacos
7、重启服务
8、查看sentinel
四、限流规则
1、簇点链路:
就是项目内的调用链路,链路中被监控的每个接口就是一个资源。默认情况下sentinel会监控SpringMVC的每一个端点(Endpoint),因此SpringMVC的每一个端点(Endpoint)就是调用链路中的一个资源。
2、新增流控规则;
(1)选择增加流控
(2)阈值设置为5,并点击新增
(3)启动jmeter,进行压力测试
(4)发现阈值应用成功了
3、流控模式
(1)关联模式
定义:
统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流
适用场景:
- 比如用户支付时需要修改订单状态,同时用户要查询订单。查询和修改操作会争抢数据库锁,产生竞争。
- 业务需求是有限支付和更新订单的业务,因此当修改订单业务触发阈值时,需要对查询订单业务限流。
(2)链路模式
4、流控效果
•快速失败:达到阈值后,新的请求会被立即拒绝并抛出FlowException异常。是默认的处理方式。
•warm up :预热模式,对超出阈值的请求同样是拒绝并抛出异常。但这种模式阈值会动态变化,从一个较小值逐渐增加到最大阈值。
• 排队等待:让所有的请求按照先后次序排队执行,两个请求的间隔不能小于指定时长
5、热点参数限流
五、隔离和降级
1、Feign整合Sentinel
(1)修改yml文件
sentinel:
enabled: true #开启Feign功能
(2)定义实现类,实现FallbackFactory
java
@Slf4j
public class UserClientFallbackFactory implements FallbackFactory<UserClient> {
@Override
public UserClient create(Throwable throwable) {
return new UserClient() {
@Override
public User findById(Long id) {
log.error("查询用户失败",throwable);
return new User();
}
};
}
}
(3)在配置类中定义Bean
java
@Bean
public UserClientFallbackFactory userClientFallbackFactory(){
return new UserClientFallbackFactory();
}
(4)在接口中实现UserClientFallbackFactory
java
@FeignClient(value = "userservice",fallbackFactory = UserClientFallbackFactory.class)
public interface UserClient {
@GetMapping("/user/{id}")
User findById(@PathVariable("id") Long id);
}
2、线程隔离(舱壁模式)
方式:
(1)线程池隔离
优点:
- 支持主动超时
- 支持异步调用
缺点:
- 线程的额外开销比较大
场景:
- 低扇出
(2)信号量隔离(默认)
优点:
- 轻量级
- 无额外开销
缺点:
- 不支持主动超时
- 不支持异步调用
场景:
- 高频调用
- 高扇出
3、熔断降级
- 熔断降级是解决雪崩问题的重要手段。
- 其思路是由断路器统计服务调用的异常比例、慢请求比例,如果超出阈值则会熔断该服务。
- 即拦截访问该服务的一切请求;而当服务恢复时,断路器会放行访问该服务的请求。
策略:
(1)慢调用
- 业务的响应时长(RT)大于指定时长的请求认定为慢调用请求。
- 在指定时间内,如果请求数量超过设定的最小数量,慢调用比例大于设定的阈值,则触发熔断。
(2)异常比例、异常数
- 统计指定时间内的调用,如果调用次数超过指定请求数,并且出现异常的比例达到设定的比例阈值(或超过指定异常数),则触发熔断。
4、授权规则
方式:
(1)白名单:来源(origin)在白名单内的调用者允许访问
(2)黑名单:来源(origin)在黑名单内的调用者不允许访问
为微服务添加授权规则:
(1)在微服务上添加类,获取请求头
java
public class HeaderOriginParser implements RequestOriginParser {
@Override
public String parseOrigin(HttpServletRequest httpServletRequest) {
//获取请求头
String origin = httpServletRequest.getHeader("origin");
//非空判断
if (StringUtils.isEmpty(origin)){
origin = "blanek";
}
return origin;
}
}
(2)目前没有请求头,所以我们要为其添加请求头
(3)在sentinel中添加授权
(4)通过order直接访问(被拦截)
(5)通过网关访问(访问成功)
5、自定义异常结果
(1)默认情况下,发生限流、降级、授权拦截时,都会抛出异常到调用方。如果要自定义异常时的返回结果,需要实现BlockExceptionHandler接口:
java
@Component
public class SentinelExceptionHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
String msg = "未知异常";
int status = 429;
if (e instanceof FlowException) {
msg = "请求被限流了";
} else if (e instanceof ParamFlowException) {
msg = "请求被热点参数限流";
} else if (e instanceof DegradeException) {
msg = "请求被降级了";
} else if (e instanceof AuthorityException) {
msg = "没有权限访问";
status = 401;
}
response.setContentType("application/json;charset=utf-8");
response.setStatus(status);
response.getWriter().println("{\"msg\": " + msg + ", \"status\": " + status + "}");
}
}
(2)测试,使用order直接访问(根据不同的原因返回不同的结果)
(3)使用网关访问
6、规则持久化
规则管理模式:
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------|-----------------------------------|
| 推送模式 | 说明 | 优点 | 缺点 |
| 原始模式 | API 将规则推送至客户端并直接更新到内存中,扩展写数据源(WritableDataSource),默认就是这种 | 简单,无任何依赖 | 不保证一致性;规则保存在内存中,重启即消失。严重不建议用于生产环境 |
| Pull模式 | 扩展写数据源(WritableDataSource), 客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件 等 | 简单,无任何依赖;规则持久化 | 不保证一致性;实时性不保证,拉取过于频繁也可能会有性能问题。 |
| Push****模式 | 扩展读数据源(ReadableDataSource),规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用 Nacos、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证。生产环境下一般采用push模式的数据源。 | 规则持久化;一致性; | 引入第三方依赖 |