抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

Sentinel 使用

什么是服务雪崩效应

​ 服务雪崩效应是一种因“服务提供者服务的不可用”(原因)导致“服务调用者服务不可用”(结果),并将不可用逐渐放大的现象。如下图所示

形成原因

服务雪崩的过程可以分为三个阶段:

  • 服务提供者不可用;
  • 重试加大请求流量;
  • 服务调用者不可用;

服务雪崩的每个阶段都可能由不同的原因造成,总结如下:

应对策略

常见容错方案
  1. 超时
  2. 限流
  3. 舱壁模式(如每个controller都有自己独立的线程池,之间互不干扰)
  4. 断路器模式

全面应对策略

Sentinel 简介

概述

​ 在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以通过 RPC 相互调用,在 Spring Cloud 中可以用 RestTemplate + LoadBalanceClientFeign 来调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证 100% 可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet 容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的 “雪崩” 效应。

​ 为了解决这个问题,业界提出了熔断器模型。

​ 阿里巴巴开源了 Sentinel 组件,实现了熔断器模式,Spring Cloud 对这一组件进行了整合。在微服务架构中,一个请求需要调用多个服务是非常常见的,如下图:

​ 较底层的服务如果出现故障,会导致连锁故障。当对特定的服务的调用的不可用达到一个阀值熔断器将会被打开。

熔断器打开后,为了避免连锁故障,通过 fallback 方法可以直接返回一个固定值。

Sentinel是什么

​ 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

​ sentinel即哨兵,相比hystrix断路器而言,它的功能更丰富。hystrix仅支持熔断,当服务消费方调用提供方发现异常后,进入熔断;sentinel不仅支持异常熔断,也支持响应超时熔断,另外还支持限流,以及针对网关的熔断和限流。此外,它还有过载处理、监控控制台(Sentinel Dashboard)等。hystrix作为组件集成到微服务中,sentinel也是如此,但它的控制台需要独立部署。

和Hystrix 对比

对比内容 Sentinel Hystrix
隔离策略 信号量隔离 线程池隔离/信号量隔离
熔断降级策略 基于响应时间或失败比率 基于失败比率
实时指标实现 滑动窗口 滑动窗口(基于 RxJava)
规则配置 支持多种数据源 支持多种数据源
扩展性 多个扩展点 插件的形式
基于注解的支持 支持 支持
限流 基于 QPS,支持基于调用关系的限流 不支持
流量整形 支持慢启动、匀速器模式 不支持
系统负载保护 支持 不支持
控制台 开箱即用,可配置规则、查看秒级监控、机器发现等 不完善
常见框架的适配 Servlet、Spring Cloud、Dubbo、gRPC 等 Servlet、Spring Cloud Netflix

关于Sentinel与Hystrix的区别见:https://yq.aliyun.com/articles/633786/

总体来说

​ Hystrix常用的线程池隔离会造成线程上下切换的overhead比较大;Hystrix使用的信号量隔离对某个资源调用的并发数进行控制,效果不错,但是无法对慢调用进行自动降级;Sentinel通过并发线程数的流量控制提供信号量隔离的功能;

​ 此外,Sentinel支持的熔断降级维度更多,可对多种指标进行流控、熔断,且提供了实时监控和控制面板,功能更为强大。

Sentinel功能特点

丰富的应用场景

​ Sentinel承接了阿里巴巴近10年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、实时熔断下游不可用应用等。

完备的实时监控

​ Sentinel同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至500台以下规模的集群的汇总运行情况。

广泛的开源生态

​ Sentinel提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入Sentinel。

完善的 SPI 扩展点

​ Sentinel提供简单易用、完善的SPI扩展点。您可以通过实现扩展点,快速的定制逻辑。例如定制规则管理、适配数据源等。

开源生态

Sentinel 分为两个部分
核心库(Java 客户端)

​ 不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。

控制台(Dashboard)

​ 基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。

整合Sentinel

导入POM依赖

1
2
3
4
5
6
7
8
9
10
<!--健康检查依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>

暴漏健康检查端点

在客户端的 application.properties 配置

1
2
3
4
#添加sentinel依赖后 暴露/actuator/sentinel端点
# 开启健康检查
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=ALWAYS

启动服务访问http://localhost:port/actuator/sentinel会返回json信息,说明已经整合好了Sentinel

配置控制台参数

在客户端的 application.properties 配置

1
2
3
4
5
#打开/关闭掉对Spring MVC端点的保护
spring.cloud.sentinel.filter.enabled=true
spring.cloud.sentinel.transport.port=8719
#指定sentinel控制台的地址
spring.cloud.sentinel.transport.dashboard=127.0.0.1:8080

搭建Sentinel控制台

下载Sentinel控制台:https://github.com/alibaba/Sentinel/releases

运行sentinel-dashboard 模块的 DashboardApplication 启动类

启动测试

启动客户端以及控制台

并调用 客户端http://localhost:8083/order/createorder/1 接口进行测试

Feign中应用Sentinel

修改配置文件

Sentinel 适配了 Feign 组件。但默认是关闭的。需要在配置文件中配置打开它。

1
2
3
4
#使用httpclient作为通讯工具
feign.httpclient.enabled=true
# feign sentinel 开启或关闭
feign.sentinel.enabled=true

创建熔断器类

创建一个实体类,实现Feign的业务接口,并重写业务接口中的所有方法,每个方法返回对应的空业务数据,保证在调用其它微服务业务出现异常后返回一个无意义的空业务数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Component
public class UserServiceFallbackFactory implements FallbackFactory<UserService> {

@Override
public UserService create(Throwable throwable) {
return new UserService() {
@Override
public Order addOrder(String userid) {
return null;
}

@Override
public String query(Order order) {

String errorMsage = "查询订单异常.......,errorMessage:" + throwable.toString();
System.out.println(errorMsage);
return errorMsage;
}
};
}
}

Feign接口配置FallbackFactory

在Feign接口的类上,添加FallbackFactory属性,指定该业务接口对应的实现类,在Feign调用其它微服务业务出现异常时会调用对应实现类中的无业务数据接口,保证接口能返回数据即可,即便是一个空的无意义数据也行。

1
2
3
4
5
6
7
8
9
10
11
@FeignClient(name = "order-server", path = "/order", fallbackFactory = UserServiceFallbackFactory.class)
public interface UserService {

@GetMapping("/createorder/{userid}")
public Order addOrder(@PathVariable("userid") String userid);


@PostMapping("/query")
public String query(@RequestBody Order order);

}

被调用方代码

如果访问线程号能够被2 整除就抛出异常

1
2
3
4
5
6
7
8
9
10
public String query(Order order) {
System.out.println(order);
System.out.println("调用查询接口,线程号:" + Thread.currentThread().getId());
if (Thread.currentThread().getId() % 2 == 0) {
int k = 1 / 0;
System.out.println("出现了异常,线程号:" + Thread.currentThread().getId());

}
return "调用查询接口...";
}

熔断测试

启动nacos中心服务,启动对应的各个微服务,首先正常情况下访问某个微服务接口,是可以正常返回接口中调用其它微服务的业务数据的。然后关闭调用的其它微服务,再访问该接口,该接口不会返回异常,也会返回数据,但是调用其它微服务返回的数据是无业务意义的数据。这就表示sentinel熔断起作用了。

评论