随着微服务的流行,服务和服务之间的稳定性变得越来越重要。 Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Sentinel 具有以下特征:
丰富的应用场景: Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、实时熔断下游不可用应用等。
完备的实时监控: Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
广泛的开源生态: Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
完善的 SPI 扩展点: Sentinel 提供简单易用、完善的 SPI 扩展点。您可以通过实现扩展点,快速的定制逻辑。例如定制规则管理、适配数据源等。
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cspgroupId>
<artifactId>sentinel-annotation-aspectjartifactId>
<version>1.8.1version>
dependency>
<dependency>
<groupId>com.alibaba.cspgroupId>
<artifactId>sentinel-transport-simple-httpartifactId>
<version>1.8.1version>
dependency>
最简单的使用 Sentinel
的例子:
启动类:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
业务层:
@Service
public class TestService {
@SentinelResource(value = "sayHello")
public String sayHello(String name) {
return "Hello, " + name;
}
}
控制层:
@RestController
public class TestController {
@Autowired
private TestService service;
@GetMapping(value = "/hello/{name}")
public String apiHello(@PathVariable String name) {
return service.sayHello(name);
}
}
@SentinelResource
注解用来标识资源是否被限流、降级。
上述例子上该注解的属性 sayHello
表示资源名
。还提供了其它额外的属性如 blockHandler,blockHandlerClass,fallback 用于表示限流或降级的操作。
注:一般推荐将 @SentinelResource
注解加到服务实现上。
Sentinel 控制台提供一个轻量级的控制台,它提供机器发现、单机资源实时监控、集群资源汇总,以及规则管理的功能。您只需要对应用进行简单的配置,就可以使用这些功能。
可以从 release 页面 下载最新版本的控制台 jar 包。
Sentinel 控制台是一个标准的 Spring Boot 应用,以 Spring Boot 的方式运行 jar 包即可。
在java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
如若8080端口冲突,可使用 -Dserver.port=新端口
进行设置。
配置控制台信息:application.yml
spring:
cloud:
sentinel:
transport:
port: 8719
dashboard: localhost:8080
这里的 spring.cloud.sentinel.transport.port
端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互。比如 Sentinel 控制台添加了一个限流规则,会把规则数据 push 给这个 Http Server 接收,Http Server 再将规则注册到 Sentinel 中。
引入依赖:
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
配置文件打开 Sentinel 对 Feign 的支持:feign.sentinel.enabled=true
FeignClient简单使用示例:
@FeignClient(name = "service-provider", fallback = EchoServiceFallback.class, configuration = FeignConfiguration.class)
public interface EchoService {
@RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
String echo(@PathVariable("str") String str);
}
class FeignConfiguration {
@Bean
public EchoServiceFallback echoServiceFallback() {
return new EchoServiceFallback();
}
}
class EchoServiceFallback implements EchoService {
@Override
public String echo(@PathVariable("str") String str) {
return "echo fallback";
}
}
EchoService
接口中方法 echo
对应的资源名为 GET:http://service-provider/echo/{str}
。
Spring Cloud Alibaba Sentinel
支持对 RestTemplate
的服务调用使用 Sentinel 进行保护,在构造 RestTemplate bean的时候需要加上 @SentinelRestTemplate
注解。
@Bean
@SentinelRestTemplate(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class)
public RestTemplate restTemplate() {
return new RestTemplate();
}
@SentinelRestTemplate
注解的属性支持限流(blockHandler, blockHandlerClass)和降级(fallback, fallbackClass)的处理。
其中 blockHandler 或 fallback 属性对应的方法必须是对应 blockHandlerClass 或 fallbackClass 属性中的静态方法。
该方法的参数跟返回值跟 org.springframework.http.client.ClientHttpRequestInterceptor#interceptor 方法一致,其中参数多出了一个 BlockException 参数用于获取 Sentinel 捕获的异常。
比如上述 @SentinelRestTemplate 注解中 ExceptionUtil 的 handleException 属性对应的方法声明如下:
public class ExceptionUtil {
public static ClientHttpResponse handleException(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException exception) {
...
}
}
注意:应用启动的时候会检查 @SentinelRestTemplate 注解对应的限流或降级方法是否存在,如不存在会抛出异常。
@SentinelRestTemplate 注解的限流(blockHandler, blockHandlerClass)和降级(fallback, fallbackClass)属性不强制填写。
当使用 RestTemplate 调用被 Sentinel 熔断后,会返回 RestTemplate request block by sentinel 信息,或者也可以编写对应的方法自行处理返回信息。这里提供了 SentinelClientHttpResponse 用于构造返回信息。
Sentinel RestTemplate 限流的资源规则提供两种粒度
:
httpmethod:schema://host:port/path:协议、主机、端口和路径
httpmethod:schema://host:port:协议、主机和端口
例如:以 https://www.taobao.com/test
这个 url 并使用 GET 方法为例。对应的资源名有两种粒度,分别是 GET:https://www.taobao.com
以及 GET:https://www.taobao.com/test
Sentinel 支持对 Spring Cloud Gateway、Zuul 等主流的 API Gateway 进行限流。
Sentinel 1.6.0 引入了 Sentinel API Gateway Adapter Common
模块,此模块中包含网关限流的规则和自定义 API 的实体和管理逻辑:
引入依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
同时请将 spring.cloud.sentinel.filter.enabled
配置项置为 false
(若在网关流控控制台上看到了 URL 资源,就是此配置项没有置为 false)。
Sentinel 提供了 Zuul 1.x 的适配模块,可以为 Zuul Gateway 提供两种资源维度的限流:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-zuul-adapter</artifactId>
<version>版本</version>
</dependency>
引入依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
同时请将 spring.cloud.sentinel.filter.enabled
配置项置为 false
(若在网关流控控制台上看到了 URL 资源,就是此配置项没有置为 false)。
*注意:网关流控规则数据源类型是 gw-flow
,若将网关流控规则数据源指定为 flow 则不生效。
从 1.6.0 版本开始,Sentinel 提供了 Spring Cloud Gateway 的适配模块,可以提供两种资源维度的限流:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
<version>版本</version>
</dependency>
在使用 Endpoint 特性之前需要在 Maven 中添加 spring-boot-starter-actuator
依赖,并在配置中允许 Endpoints 的访问。
Spring Boot 1.x 中添加配置 management.security.enabled=false
。暴露的 endpoint 路径为 /sentinel
Spring Boot 2.x 中添加配置 management.endpoints.web.exposure.include=*
。暴露的 endpoint 路径为 /actuator/sentinel
Sentinel Endpoint 里暴露的信息非常有用。包括当前应用的所有规则信息、日志目录、当前实例的 IP,Sentinel Dashboard 地址,Block Page,应用与 Sentinel Dashboard 的心跳频率等等信息。
下表显示当应用的 ApplicationContext
中存在对应的Bean的类型时,会进行自动化设置:
存在Bean的类型 | 操作 | 作用 |
---|---|---|
|
|
资源清理(资源(比如将满足 /foo/:id 的 URL 都归到 /foo/* 资源下)) |
|
|
自定义限流处理逻辑 |
|
|
设置来源信息 |
Spring Cloud Alibaba Sentinel 提供了这些配置选项:
配置项 | 含义 | 默认值 |
---|---|---|
|
Sentinel项目名 |
|
|
Sentinel自动化配置是否生效 |
true |
|
是否提前触发 Sentinel 初始化 |
false |
|
应用与Sentinel控制台交互的端口,应用本地会起一个该端口占用的HttpServer |
8719 |
|
Sentinel 控制台地址 |
|
|
应用与Sentinel控制台的心跳间隔时间 |
|
|
此配置的客户端IP将被注册到 Sentinel Server 端 |
|
|
Servlet Filter的加载顺序。Starter内部会构造这个filter |
Integer.MIN_VALUE |
|
数据类型是数组。表示Servlet Filter的url pattern集合 |
/* |
|
Enable to instance CommonFilter |
true |
|
metric文件字符集 |
UTF-8 |
|
Sentinel metric 单个文件的大小 |
|
|
Sentinel metric 总文件数量 |
|
|
Sentinel 日志文件所在的目录 |
|
|
Sentinel 日志文件名是否需要带上 pid |
false |
|
自定义的跳转 URL,当请求被限流时会自动跳转至设定好的 URL |
|
|
WarmUp 模式中的 冷启动因子 |
3 |
|
SentinelZuulPreFilter 的 order |
10000 |
|
SentinelZuulPostFilter 的 order |
1000 |
|
SentinelZuulErrorFilter 的 order |
-1 |
|
Spring Cloud Gateway 流控处理逻辑 (选择 |
|
|
Spring Cloud Gateway 响应模式为 'redirect' 模式对应的重定向 URL |
|
|
Spring Cloud Gateway 响应模式为 'response' 模式对应的响应内容 |
|
|
Spring Cloud Gateway 响应模式为 'response' 模式对应的响应码 |
429 |
|
Spring Cloud Gateway 响应模式为 'response' 模式对应的 content-type |
application/json |
Note
|
请注意。这些配置只有在 Servlet 环境下才会生效,RestTemplate 和 Feign 针对这些配置都无法生效 |
https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel
https://github.com/alibaba/Sentinel/wiki/网关限流