手记

Sentinel不同的流控效果学习

概述

本文介绍了Sentinel的不同流控效果,包括QPS限流、线程池限流和排队等待限流,每种流控方式都有其独特的应用场景。通过合理配置这些流控策略,可以有效限制请求流量,保护系统稳定运行。文章详细讲解了每种流控方式的规则配置及应用场景,帮助读者更好地理解和使用Sentinel不同的流控效果。

引入Sentinel及其重要性

Sentinel 是阿里巴巴开源的一款分布式服务保护框架,旨在提供全面的服务治理能力,包括流量控制、熔断降级、系统负载保护等。在微服务架构盛行的今天,服务之间的依赖关系错综复杂,一旦某个服务出现故障,可能会引发连锁反应,导致整个系统瘫痪。Sentinel 通过灵活的规则配置和强大的保护机制,能够有效地避免此类问题的发生。

Sentinel 的设计基于“异步”和“非阻塞”的理念,其核心是基于事件驱动的模式,可以高效地监控和管理服务间的调用关系。Sentinel 提供了三种核心功能:流量控制、熔断降级和系统保护。这些功能共同构成了一个全面的服务治理框架,能够有效地保护系统的稳定性和安全性。

初步配置示例

import com.alibaba.csp.sentinel.init.InitFunc;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;

public class SentinelInitializer implements InitFunc {

    @Override
    public void init() {
        // 配置一个基本的QPS限流规则
        FlowRule rule = new FlowRule();
        rule.setResource("exampleResource"); // 设置资源名称
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // 设置阈值类型为QPS
        rule.setCount(10); // 设置每秒的最大请求数为10
        rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); // 设置流控效果为默认效果

        // 将规则添加到Sentinel管理器
        FlowRuleManager.loadRules(Collections.singletonList(rule));
    }
}
流控效果概览

Sentinel 提供了多种流控效果,包括 QPS 限流、线程池限流、排队等待限流等,每种流控方式都有其独特的应用场景。通过合理地配置这些流控策略,可以有效地限制请求流量,保护系统不被压垮。

初步配置示例

import com.alibaba.csp.sentinel.init.InitFunc;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;

public class SentinelInitializer implements InitFunc {

    @Override
    public void init() {
        // 配置一个基本的QPS限流规则
        FlowRule qpsRule = new FlowRule();
        qpsRule.setResource("exampleResource"); // 设置资源名称
        qpsRule.setGrade(RuleConstant.FLOW_GRADE_QPS); // 设置阈值类型为QPS
        qpsRule.setCount(10); // 设置每秒的最大请求数为10
        qpsRule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); // 设置流控效果为默认效果

        // 配置一个基本的线程池限流规则
        FlowRule threadPoolRule = new FlowRule();
        threadPoolRule.setResource("exampleThreadPoolResource"); // 设置资源名称
        threadPoolRule.setGrade(RuleConstant.FLOW_GRADE_THREAD); // 设置阈值类型为线程池
        threadPoolRule.setCount(10); // 设置线程池的最大线程数为10
        threadPoolRule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); // 设置流控效果为默认效果

        // 配置一个基本的排队等待限流规则
        FlowRule queueRule = new FlowRule();
        queueRule.setResource("exampleQueueResource"); // 设置资源名称
        queueRule.setGrade(RuleConstant.FLOW_GRADE_SYSTEM); // 设置阈值类型为系统
        queueRule.setCount(10); // 设置队列的最大长度为10
        queueRule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); // 设置流控效果为默认效果

        // 将规则添加到Sentinel管理器
        FlowRuleManager.loadRules(Arrays.asList(qpsRule, threadPoolRule, queueRule));
    }
}

QPS 限流

QPS 限流是基于请求的频率来限制请求流量,通过设置每秒允许的最大请求数,可以有效地控制服务的访问压力。例如,可以设置每秒允许的最大请求数为 100,那么在一秒内,该服务最多只能处理 100 个请求。

线程池限流

线程池限流是通过限制服务能够使用的线程池资源来控制请求流量,避免服务因为线程池资源耗尽而无法处理请求。例如,可以设置一个线程池,最大线程数为 10,那么在一秒内,该服务最多只能处理 10 个并发请求。

排队等待限流

排队等待限流是通过设置请求队列的长度来限制请求流量,当请求队列已满时,新来的请求将被放入等待队列,直到队列中有空闲资源。这种方法适合于需要保证请求顺序处理的场景,可以有效地避免请求丢失。

QPS 限流学习

QPS 限流是 Sentinel 最基础也是最常用的流控策略之一,通过限制服务每秒处理的最大请求量,可以有效地控制服务的访问压力。QPS 限流的规则配置简单明了,只需要设置每秒允许的最大请求数即可。

QPS 限流规则配置

在 Sentinel 中,QPS 限流规则通过 FlowRule 对象进行配置。FlowRule 对象包含了一些重要的属性,如资源名称、阈值类型、计数器类型、流控效果等。以下是 QPS 限流规则配置的示例代码:

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;

public class QpsController {

    public static void main(String[] args) {
        // 配置 QPS 限流规则
        FlowRule rule = new FlowRule();
        rule.setResource("exampleResource"); // 设置资源名称
        rule.setGrade(FlowRuleManager.GRADER_QPS_COUNT); // 设置阈值类型为 QPS
        rule.setCount(10); // 设置每秒的最大请求数为 10
        rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); // 设置流控效果为默认效果
        rule.setWarmUpPeriodMs(1000); // 设置预热时间

        // 将规则添加到 Sentinel 管理器
        FlowRuleManager.loadRules(Collections.singletonList(rule));

        // 示例方法
        for (int i = 0; i < 100; i++) {
            try {
                exampleMethod();
            } catch (BlockException e) {
                System.out.println("请求被限流了:" + e.getMessage());
            }
        }
    }

    @SentinelResource(value = "exampleResource", blockHandler = "blockHandler")
    public void exampleMethod() {
        System.out.println("请求通过了限流检查");
    }

    public void blockHandler(BlockException ex) {
        System.out.println("请求被限流了:" + ex.getMessage());
    }
}

QPS 限流示例

在上述示例代码中,我们配置了一个 QPS 限流规则,将每秒允许的最大请求数设置为 10。通过循环调用 exampleMethod 方法,当请求量超过每秒 10 个时,请求将被限流,blockHandler 方法将被调用。

预热时间

在 QPS 限流策略中,可以通过设置预热时间来实现平滑限流的效果。预热时间的设置可以有效避免突然增加请求量时对服务造成冲击。例如,可以设置预热时间为 1000 毫秒,那么在开始计数之前,Sentinel 会先逐步增加请求量,直到达到最大允许的请求量。

QPS 限流的应用场景

QPS 限流策略适用于几乎所有需要限制服务访问压力的场景。例如,在高并发场景下,可以设置每秒允许的最大请求数,避免服务被大量请求压垮。此外,QPS 限流还可以用于控制 API 的访问频率,防止恶意攻击或滥用。

线程池限流学习

线程池限流是 Sentinel 提供的一种高级流控策略,通过限制服务能够使用的线程池资源来控制请求流量。线程池限流的规则配置相对复杂,需要设置线程池的最大线程数、核心线程数、是否阻塞等属性。

线程池限流规则配置

在 Sentinel 中,线程池限流规则通过 FlowRule 对象进行配置。FlowRule 对象包含了一些重要的属性,如资源名称、阈值类型、计数器类型、流控效果等。以下是线程池限流规则配置的示例代码:

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;

public class ThreadPoolController {

    public static void main(String[] args) {
        // 配置线程池限流规则
        FlowRule rule = new FlowRule();
        rule.setResource("exampleResource"); // 设置资源名称
        rule.setGrade(FlowRuleManager.GRADER_THREADPOOL); // 设置阈值类型为线程池
        rule.setCount(10); // 设置线程池的最大线程数为 10
        rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); // 设置流控效果为默认效果

        // 将规则添加到 Sentinel 管理器
        FlowRuleManager.loadRules(Collections.singletonList(rule));

        // 示例方法
        for (int i = 0; i < 100; i++) {
            try {
                exampleMethod();
            } catch (BlockException e) {
                System.out.println("请求被限流了:" + e.getMessage());
            }
        }
    }

    @SentinelResource(value = "exampleResource", blockHandler = "blockHandler")
    public void exampleMethod() {
        System.out.println("请求通过了限流检查");
    }

    public void blockHandler(BlockException ex) {
        System.out.println("请求被限流了:" + ex.getMessage());
    }
}

线程池限流示例

在上述示例代码中,我们配置了一个线程池限流规则,将线程池的最大线程数设置为 10。通过循环调用 exampleMethod 方法,当请求量超过线程池的最大线程数时,请求将被限流,blockHandler 方法将被调用。

核心线程数和最大线程数

在线程池限流策略中,可以通过设置核心线程数和最大线程数来控制服务能够使用的线程资源。核心线程数是指线程池中总是保持的线程数,当核心线程数达到上限时,新来的请求将进入等待队列。最大线程数是指线程池中允许的最大线程数,当核心线程数不足以处理所有请求时,线程池会创建新的线程来处理请求。

是否阻塞

在线程池限流策略中,可以通过设置是否阻塞来控制服务处理请求的行为。如果设置为阻塞,则当线程池资源耗尽时,新来的请求将被阻塞,直到有空闲资源可用。如果设置为非阻塞,则当线程池资源耗尽时,新来的请求将被直接拒绝。

线程池限流的应用场景

线程池限流策略适用于需要控制线程资源使用的场景。例如,在高并发场景下,可以通过设置线程池的最大线程数来限制服务能够使用的线程资源,避免服务因为线程资源耗尽而无法处理请求。此外,线程池限流还可以用于控制服务的并发处理能力,确保服务能够高效地处理请求。

排队等待限流学习

排队等待限流是 Sentinel 提供的一种高级流控策略,通过设置请求队列的长度来限制请求流量。排队等待限流的规则配置相对复杂,需要设置队列长度、是否阻塞等属性。

排队等待限流规则配置

在 Sentinel 中,排队等待限流规则通过 FlowRule 对象进行配置。FlowRule 对象包含了一些重要的属性,如资源名称、阈值类型、计数器类型、流控效果等。以下是排队等待限流规则配置的示例代码:

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;

public class QueueController {

    public static void main(String[] args) {
        // 配置排队等待限流规则
        FlowRule rule = new FlowRule();
        rule.setResource("exampleResource"); // 设置资源名称
        rule.setGrade(FlowRuleManager.GRADER_SYSTEM); // 设置阈值类型为系统
        rule.setCount(10); // 设置队列的最大长度为 10
        rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); // 设置流控效果为默认效果

        // 将规则添加到 Sentinel 管理器
        FlowRuleManager.loadRules(Collections.singletonList(rule));

        // 示例方法
        for (int i = 0; i < 100; i++) {
            try {
                exampleMethod();
            } catch (BlockException e) {
                System.out.println("请求被限流了:" + e.getMessage());
            }
        }
    }

    @SentinelResource(value = "exampleResource", blockHandler = "blockHandler")
    public void exampleMethod() {
        System.out.println("请求通过了限流检查");
    }

    public void blockHandler(BlockException ex) {
        System.out.println("请求被限流了:" + ex.getMessage());
    }
}

排队等待限流示例

在上述示例代码中,我们配置了一个排队等待限流规则,将队列的最大长度设置为 10。通过循环调用 exampleMethod 方法,当请求队列已满时,请求将被限流,blockHandler 方法将被调用。

队列长度

在排队等待限流策略中,可以通过设置队列长度来控制服务能够处理的请求数量。队列长度是指队列中允许的最大请求数,当队列已满时,新来的请求将被拒绝或阻塞。

是否阻塞

在排队等待限流策略中,可以通过设置是否阻塞来控制服务处理请求的行为。如果设置为阻塞,则当队列已满时,新来的请求将被阻塞,直到队列中有空闲资源可用。如果设置为非阻塞,则当队列已满时,新来的请求将被直接拒绝。

排队等待限流的应用场景

排队等待限流策略适用于需要保证请求顺序处理的场景。例如,在处理订单、支付等业务逻辑时,需要保证请求的顺序处理,避免请求丢失或处理顺序混乱。此外,排队等待限流还可以用于控制服务的并发处理能力,确保服务能够高效地处理请求。

实战演练:自定义流控效果

在实际的应用场景中,我们可能需要根据业务需求自定义流控效果。Sentinel 提供了灵活的规则配置和强大的保护机制,可以通过自定义流控效果来更好地保护服务。

自定义流控效果规则配置

在 Sentinel 中,可以通过设置自定义流控效果来实现更复杂的流控策略。自定义流控效果需要实现 FlowRule 对象的 getCustomControlBehavior 方法,通过该方法可以自定义流控效果的行为。

自定义流控效果示例

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;

public class CustomFlowController {

    public static void main(String[] args) {
        // 配置自定义流控效果规则
        FlowRule rule = new FlowRule();
        rule.setResource("exampleResource");
        rule.setGrade(FlowRuleManager.GRADER_CUSTOM);
        rule.setCount(10);
        rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_CUSTOM);

        // 将规则添加到 Sentinel 管理器
        FlowRuleManager.loadRules(Collections.singletonList(rule));

        // 示例方法
        for (int i = 0; i < 100; i++) {
            try {
                exampleMethod();
            } catch (BlockException e) {
                System.out.println("请求被限流了:" + e.getMessage());
            }
        }
    }

    @SentinelResource(value = "exampleResource", blockHandler = "blockHandler")
    public void exampleMethod() {
        System.out.println("请求通过了限流检查");
    }

    public void blockHandler(BlockException ex) {
        System.out.println("请求被限流了:" + ex.getMessage());
    }
}

自定义流控效果的应用场景

自定义流控效果适用于需要根据业务需求实现更复杂的流控策略的场景。例如,在处理复杂业务逻辑时,可能需要根据业务需求自定义流控效果,以更好地保护服务。此外,自定义流控效果还可以用于实现更复杂的系统保护策略,确保服务的稳定性和安全性。

总结

通过本文的介绍,我们了解了 Sentinel 的重要性及其核心功能。Sentinel 提供了多种流控策略,包括 QPS 限流、线程池限流、排队等待限流等,每种流控方式都有其独特的应用场景。通过合理地配置这些流控策略,可以有效地限制请求流量,保护系统不被压垮。同时,Sentinel 还提供了丰富的 API 和注解支持,使得开发者能够轻松地实现自定义流控效果,满足各种复杂的应用场景需求。

0人推荐
随时随地看视频
慕课网APP