详细介绍查看 官网文档:https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D

1、Hystrix与Sentinel差异

image.png

  • 隔离策略:
    • 线程池隔离:假如有100个请求(hello world)过来。规定只能放90个请求,会创建一个只能放90个线程的线程池。
      • 缺点:带来的问题就是假如有(hello,hhh,你好。。。等等好多种请求过来),那就必须创建好几个线程池,这用着用着可能系统的线程池就不够了。
      • 优点:隔离彻底,每个线程在自己的池子里面玩,自己的池子炸了和其它线程没有关系。
    • 信号量(semaphore)隔离:每个请求对应一个信号量,例如一个“hello”对应自己的一个信号量,接到一个请求信号量-1,有一个请求执行完了,就给信号量+1。
      • 缺点:一个线程炸了,整个服务都会出现问题
      • 优点:资源耗费少

        2、简单使用

1、引入jar包

  1. <dependency>
  2. <groupId>com.alibaba.cloud</groupId>
  3. <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
  4. <version>2.1.0.RELEASE</version>
  5. </dependency>

下载服务端jar包:https://github.com/alibaba/Sentinel/releases,根据spring-cloud-starter-alibaba-sentinel的版本下载对应的jar包。
image.png
本次引用的starter是 2.2.5.RELEASE ,其对应的服务端需要下载1.8.0版本的。
image.png
3、直接启动dashboard即可,java -jar sentinel-dashboard-1.8.0.jar —server.port=8333
image.png
image.png
账户密码默认:sentinel / sentinel
image.png
整个页面采用懒加载的方式,必须有请求进来才会显示相应的属性。
image.png
进行简单的设置之后
image.png
截止到这边所有的设置都是保存在内存中的,服务重启后一切设置都会失效。
流控生效之后
image.png
配置文件添加 management.endpoints.web.exposure.include=* 方便sentinel统计信息。

Endpoint 支持

在使用 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 的心跳频率等等信息。

自定义返回信息

  1. @Configuration
  2. public class SentinelConfig {
  3. public SentinelConfig() {
  4. WebCallbackManager.setUrlBlockHandler(new UrlBlockHandler() {
  5. @Override
  6. public void blocked(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws IOException {
  7. httpServletResponse.setCharacterEncoding("UTF-8");
  8. httpServletResponse.setContentType("application/json");
  9. httpServletResponse.getWriter().write("服务器扛不住啦,休息中。。。");
  10. }
  11. });
  12. }
  13. }

image.png

3、单机预热模式

image.png
十秒之内达到阈值10。

4、排队等待

image.png
阈值为10,超过部分进行排队等待,排队时间超过500ms则报错。

5、熔断降级

一般在调用方手动指定远程服务的熔断策略,
也可以在提供方做限制,返回的都是默认的降级数据。
RT:响应时间
image.png
当1秒内持续进入5个请求,这些请求对应时刻的平均响应时间均超过阀值(上图中为5ms),那么在接下来的时间窗口(10s)之内,对这个方法的调用都会自动熔断。

6、自定义受保护的资源

  1. @GetMapping("hello2/{name}")
  2. public String hello2(@PathVariable String name) {
  3. print();
  4. return name;
  5. }
  6. private void print() {
  7. // ----------
  8. try (Entry print = SphU.entry("print")) {
  9. System.out.println("hello world!");
  10. } catch (BlockException e) {
  11. System.out.println("资源被限制" + e.getMessage());
  12. }
  13. }

image.png
image.png

7、基于注解自定义配置

  1. @Service
  2. public class testService {
  3. @SentinelResource(value = "testService", blockHandler = "blockHandler", fallback = "fallback")
  4. public void print() {
  5. System.out.println("testService.......");
  6. }
  7. public void blockHandler(BlockException e) {
  8. System.out.println("testService.blockHandler:" + e.getMessage());
  9. }
  10. public void fallback() {
  11. System.out.println("fallback..........");
  12. }
  13. }
  1. @GetMapping("hello4/{name}")
  2. public String hello4(@PathVariable String name) {
  3. service.print();
  4. return name;
  5. }

注意 blockHandler 函数会在原方法被限流/降级/系统保护的时候调用,而 fallback 函数会针对所有类型的异常。请注意 blockHandlerfallback 函数的形式要求

8、自定义其他blockHandler类和fallback

  1. public class BlockHandler {
  2. public static String helloWorld(BlockException blockException) {
  3. System.out.println("太快了.........,请慢点");
  4. return "1";
  5. }
  6. }
  1. public class FallbackHandler {
  2. public static String helloWorld3() {
  3. System.out.println("FallbackHandler.helloWorld.........");
  4. return "";
  5. }
  6. }
  1. @SentinelResource(value = "helloWorld", blockHandler = "helloWorld", blockHandlerClass = BlockHandler.class)
  2. public String helloWorld() {
  3. System.out.println("helloWorld.........");
  4. return null;
  5. }
  6. @SentinelResource(value = "helloWorld3", fallbackClass = FallbackHandler.class, fallback = "helloWorld3")
  7. public String helloWorld3() {
  8. int a = 1 / 0;
  9. System.out.println("helloWorld.........");
  10. return "";
  11. }