欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中Sentinel框架詳解

 更新時間:2023年06月07日 08:43:49   作者:大家都說我身材好  
Sentinel是一個高可用、高擴展、高穩(wěn)定性的開源流量控制和熔斷降級框架,可以在分布式系統(tǒng)中實現(xiàn)實時的流量控制,防止系統(tǒng)因流量過大導致系統(tǒng)崩潰和服務(wù)降級,Sentinel面向所有的Java應(yīng)用,本文就給大家詳細介紹一下Java中Sentinel框架,需要的朋友可以參考下

一、簡介

Sentinel 是一個高可用、高擴展、高穩(wěn)定性的開源流量控制和熔斷降級框架,可以在分布式系統(tǒng)中實現(xiàn)實時的流量控制,防止系統(tǒng)因流量過大導致系統(tǒng)崩潰和服務(wù)降級。

Sentinel 提供了以下功能:

  • 流量控制:通過配置不同的規(guī)則,對請求流量進行限制。
  • 熔斷降級:當系統(tǒng)異常情況發(fā)生時,可以自動熔斷系統(tǒng),保證系統(tǒng)的可用性。
  • 系統(tǒng)負載保護:在系統(tǒng)負載高峰期間,可以限制請求流量,避免系統(tǒng)資源耗盡。
  • 實時監(jiān)控:可以實時監(jiān)控系統(tǒng)的請求流量、響應(yīng)時間、錯誤率等指標。

Sentinel 面向所有的 Java 應(yīng)用,可以支持基于 Spring Cloud、Dubbo、gRPC 等服務(wù)框架的應(yīng)用,也可以集成到基于 Tomcat、Jetty 等 Web 容器的應(yīng)用中。

二、Sentinel 的原理

Sentinel 實現(xiàn)流量控制和熔斷降級的原理是通過對應(yīng)用程序進行攔截,然后根據(jù)預定義的規(guī)則,來判斷該請求是否被允許或者需要進行降級處理。

Sentinel 的攔截器會在應(yīng)用程序中建立一個責任鏈,對請求進行逐一攔截。在攔截過程中,Sentinel 會對 Request、Response、Exception 等參數(shù)進行統(tǒng)計,根據(jù)統(tǒng)計信息來對請求進行熔斷或者限流等操作。

衡量系統(tǒng)穩(wěn)定性主要有以下三個指標:

  • TPS(Transactions Per Second):每秒鐘處理的事務(wù)數(shù)。
  • RT(Response Time):響應(yīng)時間,即從發(fā)送請求到接收到響應(yīng)的時間。
  • Error Rate:錯誤率,即發(fā)生錯誤的請求次數(shù)占總請求數(shù)的比例。

 Sentinel 根據(jù)這三個指標來評估應(yīng)用程序的健康狀況,當這些指標達到某個閾值時,Sentinel 會自動觸發(fā)相應(yīng)的流量控制和熔斷降級操作。

三、Sentinel 快速入門

以下是 Sentinel 快速入門的幾個步驟:

  • 首先,在 Maven 中引入 Sentinel 的依賴:
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>2.2.1.RELEASE</version>
</dependency>
  • 在 Spring Boot 中配置 Sentinel 的啟動參數(shù):
spring.cloud.sentinel.transport.dashboard=http://localhost:8080
spring.cloud.sentinel.transport.port=8719
# Sentinel 控制臺連接超時時間(ms)
spring.cloud.sentinel.transport.dashboard.request-timeout=5000
# 配置資源的默認規(guī)則
spring.cloud.sentinel.rules.defaults[0].grade=QPS
spring.cloud.sentinel.rules.defaults[0].count=10

其中,spring.cloud.sentinel.transport.dashboard 配置了 Sentinel 控制臺的地址,spring.cloud.sentinel.transport.port 配置了 Sentinel 的啟動端口。

  • 在需要進行流量控制的方法上添加注解:
@SentinelResource(value = "demoMethod", blockHandler = "handleBlock")
public String demoMethod() {
  return "Hello World";
}
public String handleBlock(BlockException ex) {
  return "請求被攔截: " + ex.getClass().getSimpleName();
}

在上述代碼中,我們使用 @SentinelResource 注解對 demoMethod 方法進行了流量控制,并設(shè)置了 fallback 方法為 handleBlock。當觸發(fā)限流時,就會執(zhí)行 handleBlock 方法來返回自定義的響應(yīng)結(jié)果。

四、使用 Sentinel 進行熔斷降級

Sentinel 不僅能夠進行流量控制,還能夠進行熔斷降級。當系統(tǒng)出現(xiàn)一定程度的異常時,就會觸發(fā)熔斷降級策略來保證系統(tǒng)的可用性。以下是使用 Sentinel 進行熔斷降級的幾個步驟:

  • 在業(yè)務(wù)方法上添加 @SentinelResource 注解,并指定 fallbackClass 和 fallback 屬性值:
@SentinelResource(value = "demoMethod", blockHandler = "handleBlock", fallbackClass = DemoServiceFallback.class, fallback = "fallback")
public String demoMethod() {
  return "Hello World";
}
public String handleBlock(BlockException ex) {
  return "請求被攔截: " + ex.getClass().getSimpleName();
}
  • 在上述代碼中,我們指定了 fallbackClass 和 fallback 屬性來定義 fallback 方法的實現(xiàn)類和方法名。當服務(wù)出現(xiàn)熔斷降級時,就會執(zhí)行 fallback 方法來返回自定義的響應(yīng)結(jié)果。

  • 定義 fallback 方法及其實現(xiàn)類:

在上述代碼中,我們定義了 fallback 方法及其實現(xiàn)類 DemoServiceFallback。當服務(wù)出現(xiàn)熔斷降級時,就會執(zhí)行 fallback 方法來返回自定義的響應(yīng)結(jié)果。

五、Sentinel 的流控規(guī)則和熱點參數(shù)限流

Sentinel 支持多種多樣的流控規(guī)則和熱點參數(shù)限流策略,可以根據(jù)業(yè)務(wù)場景進行靈活配置。

流控規(guī)則

Sentinel 的流控規(guī)則有以下幾種:

  • QPS 流量控制:通過對 API 進行 QPS 控制,即限定接口在一定時間內(nèi)能夠處理的請求次數(shù)。

@SentinelResource(value = "demoMethod", blockHandler = "handleBlock")
@RateLimiter(10)
public String demoMethod() {
  return "Hello World";
}
public String handleBlock(BlockException ex) {
  return "請求被攔截: " + ex.getClass().getSimpleName();
}
  • 在上述代碼中,我們使用 @RateLimiter 注解對接口進行了 QPS 流控,并設(shè)置了限流閾值為 10。

  • 線程數(shù)流控:通過對線程池中的線程數(shù)進行限制,來避免線程池過載。

@SentinelResource(value = "demoMethod", blockHandler = "handleBlock")
@ThreadPool(name = "demoMethod", coreSize = 5, maxQueueSize = 10)
public String demoMethod() {
  return "Hello World";
}
public String handleBlock(BlockException ex) {
  return "請求被攔截: " + ex.getClass().getSimpleName();
}
  • 在上述代碼中,我們使用 @ThreadPool 注解對線程池進行了流控,并設(shè)置了線程池的核心線程數(shù)為 5。

熱點參數(shù)限流

熱點參數(shù)限流是 Sentinel 的一個重要特性,可以有效避免因某個參數(shù)的惡意使用而導致整個系統(tǒng)崩潰的情況。例如,假設(shè)有一個商品詳情接口,其中的參數(shù) skuId 很可能存在熱點,即某些具體的商品 skuId 會被大量請求。如果不進行限流,當出現(xiàn)某個特定 skuId 的惡意攻擊時,系統(tǒng)可能會崩潰。

以下是一個使用 Sentinel 實現(xiàn)熱點參數(shù)限流的示例:

@SentinelResource(value = "demoMethod", blockHandler = "handleBlock")
@HotParam(value = "skuId", mode = ParamFlowItem.FlowControlMode.QPS, threshold = 100)
public String demoMethod(@RequestParam Long skuId) {
  return "Hello World";
}

在上述代碼中,我們使用 @HotParam 注解對 skuId 參數(shù)進行限流,并設(shè)置了限流閾值為 100 QPS。這樣,當某個 skuId 的請求超過 100 QPS 時,就會觸發(fā) Sentinel 的限流機制。通過這種方式,我們可以避免因某個熱點參數(shù)的異常使用而導致整個系統(tǒng)崩潰的情況。

六、Sentinel 的優(yōu)缺點

Sentinel 作為一個成熟的分布式系統(tǒng)的流量防衛(wèi)兵,具有以下優(yōu)點:

  • 功能豐富:Sentinel 提供了流量控制、熔斷降級、系統(tǒng)保護、實時監(jiān)控等全方位的服務(wù)質(zhì)量保障。
  • 易于使用:Sentinel 提供了友好的 Web 界面,可以方便的進行規(guī)則的配置和管理。
  • 高度可定制:Sentinel 提供了多種 SPI 擴展點,可以根據(jù)業(yè)務(wù)需求進行自定義擴展。
  • 開源免費:Sentinel 是完全開源的,可以免費使用。

當然,Sentinel 還存在以下一些缺點:

  • 不支持語言多樣性:Sentinel 目前只支持 Java 應(yīng)用,對于其他編程語言的應(yīng)用不夠友好。
  • 文檔略顯簡單:Sentinel 的文檔雖然已經(jīng)比較全面,但是在一些實踐場景中仍然存在一些坑點需要注意。

七、Sentinel 高級特性

同時支持同步和異步調(diào)用

Sentinel 可以方便地支持同步和異步調(diào)用。 對于同步調(diào)用,可以使用 @SentinelResource 注解,在注解中指定需要進行保護的方法,并設(shè)置相應(yīng)的熔斷降級、流控規(guī)則等限制條件。

對于異步調(diào)用,則需要使用 Sentinel 提供的異步 Entry 類實現(xiàn)保護。 在使用異步 Entry 進行保護時,需要在異步調(diào)用過程中插入 Sentinel 的攔截器,并在異步操作完成后手動釋放相應(yīng)的資源,以便 Sentinel 統(tǒng)計并記錄相應(yīng)的數(shù)據(jù)。

例如,以下是一個使用異步 Entry 進行保護的示例:

CompletableFuture.supplyAsync(() -> {
  Entry entry = null;
  try {
    entry = SphU.asyncEntry("demoMethod");
    // 異步邏輯
    return "Hello World";
  } catch (BlockException ex) {
    return "blocked by Sentinel: " + ex.getClass().getSimpleName();
  } finally {
    if (entry != null) {
      entry.exit();
    }
  }
}).thenAccept(result -> System.out.println("result: " + result));

在上述代碼中,我們首先使用 SphU.asyncEntry 方法創(chuàng)建一個異步 Entry,然后在異步邏輯中執(zhí)行業(yè)務(wù)操作。要注意的是,當異步操作完成時,需要手動調(diào)用 entry.exit() 方法釋放相應(yīng)的資源。

支持多種限流模式

Sentinel 支持多種限流模式,可以根據(jù)實際需求選擇不同的限流算法。

  • 直接模式:直接對資源進行限制,超出閾值即觸發(fā)限流。
  • 關(guān)聯(lián)模式:通過關(guān)聯(lián)資源來進行限流,例如對某個 API 進行流量控制時,可以通過關(guān)聯(lián)訪問該 API 的數(shù)據(jù)庫連接池來實現(xiàn)流量控制。
  • 鏈路模式:通過對整個鏈路進行流量控制來保障系統(tǒng)的穩(wěn)定性。

使用關(guān)聯(lián)模式和鏈路模式時,需要在規(guī)則中設(shè)置相關(guān)的關(guān)聯(lián)鏈接和鏈路信息。

例如,以下是一個使用關(guān)聯(lián)模式進行流量控制的示例:

@SentinelResource(value = "demoMethod", blockHandler = "handleBlock")
public void demoMethod(@RequestParam("id") Long id) {
  System.out.println("request id: " + id);
}
@Bean
public RequestOriginParser requestOriginParser() {
  return new DemoRequestOriginParser();
}
public static class DemoRequestOriginParser implements RequestOriginParser {
  @Override
  public String parseOrigin(HttpServletRequest request) {
    String origin = request.getParameter("origin");
    if (StringUtils.isEmpty(origin)) {
      return "unknown";
    }
    return origin;
  }
}
@Configuration
public class SentinelConfig {
  @Autowired
  private RequestOriginParser requestOriginParser;
  @PostConstruct
  public void init() {
    FlowRuleManager.register2(Arrays.asList(
        new FlowRule("demoMethod").setCount(5)
            .setGrade(RuleConstant.FLOW_GRADE_QPS)
            .setLimitApp("default")
            .as(FlowRule.class)
            .setStrategy(RuleConstant.STRATEGY_RELATE)
            .setRefResource("demoDatabase")));
  }
  @Bean
  public SentinelResourceAspect sentinelResourceAspect() {
    return new SentinelResourceAspect();
  }
  @Bean
  public SentinelServletRequestAspect sentinelServletRequestAspect() {
    return new SentinelServletRequestAspect();
  }
}

在上述代碼中,我們使用 @SentinelResource 注解進行流量控制,并通過 setRefResource 和 setStrategy 來關(guān)聯(lián)數(shù)據(jù)庫連接池資源,并設(shè)置限流策略為關(guān)聯(lián)模式。

支持多種規(guī)則匹配方式

Sentinel 支持多種規(guī)則匹配方式,可以根據(jù)實際需求選擇不同的規(guī)則匹配策略。

  • 精確匹配:精確匹配是最常用的匹配方式,可以根據(jù)資源名稱、限流參數(shù)等精確匹配規(guī)則。
  • 子串匹配:通常用于對資源名稱進行模糊匹配,例如對某個 API 的所有請求進行限流。
  • 正則匹配:可以根據(jù)正則表達式進行規(guī)則匹配,提供更高級別的靈活性。

例如,以下是一個使用正則匹配規(guī)則的示例:

@SentinelResource(value = "demoMethod", blockHandler = "handleBlock")
public void demoMethod(@RequestBody Map<String, Object> data) {
  System.out.println("request data: " + data);
}
@Configuration
public class SentinelConfig {
  @PostConstruct
  public void init() {
    SystemRuleManager.loadRules(Collections.singletonList(
        new SystemRule()
            .setHighestSystemLoad(1.0)
            .setAvgLoad(0.8)
            .setQps(200))));
    ParamFlowRuleManager.loadRules(Collections.singletonList(
        new ParamFlowRule()
            .setParamIdx(0)
            .setGrade(RuleConstant.FLOW_GRADE_QPS)
            .setCount(5)
            .setDurationInSec(1)
            .setParamFlowItemList(Collections.singletonList(
                new ParamFlowItem().setObject("special_object")
                    .setCount(2)))));
    DegradeRuleManager.loadRules(Collections.singletonList(
        new DegradeRule("demoMethod")
            .setCount(100)
            .setTimeWindow(10)
            .setGrade(RuleConstant.DEGRADE_GRADE_RT)
            .setCount(20)
            .setMinRequestAmount(10))));
    FlowRuleManager.loadRules(Collections.singletonList(
        new FlowRule()
            .setGrade(RuleConstant.FLOW_GRADE_QPS)
            .setResourceRegex("/api/.*")
            .setCount(10)
            .setLimitApp("default")
            .as(FlowRule.class))));
  }
  @Bean
  public SentinelResourceAspect sentinelResourceAspect() {
    return new SentinelResourceAspect();
  }
}

在上述代碼中,我們使用 setResourceRegex 方法設(shè)置了一個正則匹配規(guī)則,對所有以 /api/ 開頭的資源進行流量控制。

八、使用案例

使用 Sentinel 和 Spring Cloud Gateway 實現(xiàn)網(wǎng)關(guān)限流

首先,我們需要在項目中引入 Sentinel 和 Spring Cloud Gateway 的依賴:

<!-- 引入 Sentinel -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- 引入 Spring Cloud Gateway -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

然后,我們可以在 application.yml 文件中添加 Sentinel 和 Spring Cloud Gateway 的相關(guān)配置:

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8250
server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
        - id: test_route
          uri: http://httpbin.org
          predicates:
            - Path=/anything/**

在上面的配置中,我們指定了 Sentinel 的 dashboard 地址和 Spring Cloud Gateway 的端口號,在 Spring Cloud Gateway 中添加了一個名為 test_route 的路由,匹配路徑為 /anything/**,并將該路由轉(zhuǎn)發(fā)到 http://httpbin.org。

接下來,我們需要為 Spring Cloud Gateway 添加 Sentinel 規(guī)則,以控制請求的流量:

@Bean
public SentinelGatewayFilterFactory sentinelGatewayFilterFactory() {
    return new SentinelGatewayFilterFactory();
}
@Bean
public GatewayFilterChain gatewayFilterChain(RouteLocator routeLocator,
                                             List<GatewayFilterFactory> gatewayFilters) {
    DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(routeLocator.getRoutes(), gatewayFilters);
    chain.add(0, sentinelGatewayFilterFactory.apply(new Object()));
    return chain;
}

在上面的代碼片段中,我們創(chuàng)建了一個名為 sentinelGatewayFilterFactory 的 Bean,用于創(chuàng)建 Sentinel 的網(wǎng)關(guān)過濾器,并添加到 Gateway 中。

最后,我們需要在 Sentinel dashboard 中進行規(guī)則配置,以控制請求流量:

  • 打開 Sentinel 控制臺,在左側(cè)導航欄中,選擇 Flow,并點擊 新增。
  • 在 Resource 輸入框中輸入 /anything/**
  • 在 限流閾值 輸入框中輸入限制請求流量的最大數(shù)值。
  • 點擊 新增。

使用 Sentinel 和 RocketMQ 實現(xiàn)消息流量控制

首先,我們需要在項目中引入 Sentinel 和 RocketMQ 的依賴:

<!-- 引入 Sentinel -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- 引入 RocketMQ -->
<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-spring-boot-starter</artifactId>
    <version>2.0.3</version>
</dependency>

然后,在 application.yml 文件中添加 Sentinel 和 RocketMQ 的相關(guān)配置:

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8250
rocketmq:
  name-server: localhost:9876
  producer:
    group: my-group

其中,我們指定了 Sentinel 的 dashboard 地址和 RocketMQ 的 NameServer 地址,以及 RocketMQ 的生產(chǎn)者組名。

接下來,我們需要為生產(chǎn)者添加 Sentinel 規(guī)則,以控制消息發(fā)送的流量:

@Slf4j
@Service
public class MyProducer {
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @PostConstruct
    public void init() {
        // 添加 Sentinel 規(guī)則
        String resourceName = "myTopic:myTag";
        String ruleKey = "myRuleKey";
        int threshold = 100;
        DegradeRule rule = new DegradeRule(resourceName, ruleKey, threshold);
        rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);
        rule.setTimeWindow(10);
        List<DegradeRule> rules = new ArrayList<>();
        rules.add(rule);
        DegradeRuleManager.loadRules(rules);
    }
    public void sendMessage(String message) {
        try {
            rocketMQTemplate.convertAndSend("myTopic", "myTag", message);
        } catch (Exception e) {
            log.error("發(fā)送消息失敗,message: {}", message, e);
        }
    }
}

在上面的代碼中,我們?yōu)?myTopic:myTag 資源添加了一條 Sentinel 規(guī)則,該規(guī)則的作用是:當該資源的 RT(響應(yīng)時間)超過 10 毫秒時,將觸發(fā)熔斷,拒絕進一步的請求,防止影響消息系統(tǒng)的正常運行。規(guī)則的閾值為 100,即當一秒鐘內(nèi)超過 100 條消息時會觸發(fā)限流。

最后,在消費者中也需要添加 Sentinel 的規(guī)則,以控制消息消費的流量:

@Slf4j
@Service
public class MyConsumer {
    @RocketMQMessageListener(topic = "myTopic", consumerGroup = "my-group")
    @SentinelResource(value = "myTopic:myTag", blockHandler = "handleBlockedMessage")
    public void handleMessage(@Payload String message) {
        log.info("接收到消息:{}", message);
    }
    public void handleBlockedMessage(String message, BlockException e) {
        log.error("消息被拒絕,message: {}", message);
    }
}

在上面的代碼中,我們?yōu)?nbsp;myTopic:myTag 資源添加了 Sentinel 規(guī)則,并指定了發(fā)生 Sentinel 規(guī)則限制時的處理方法。在消費過程中,如果超過 Sentinel 規(guī)則的閾值,則會觸發(fā)限流,拒絕進一步的消息消費。

以上就是Java中Sentinel框架詳解的詳細內(nèi)容,更多關(guān)于Java Sentinel框架的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論