Alibaba Sentinel - 集群流量控制

文章系列

一、Alibaba Sentinel 基操
二、Alibaba Sentinel - 集群流量控制
三、Alibaba Sentinel - 工作流程及原理解析
四、Alibaba Sentinel - Slot chain解析
五、Alibaba Sentinel - 滑动窗口

一、集群流控介绍

集群流控可以解决流量不均匀导致总体限流效果不佳的问题。

假设集群中有 10 台机器,我们给每台机器设置单机限流阈值为 10 QPS,理想情况下整个集群的限流阈值就为 100 QPS。不过实际情况下流量到每台机器可能会不均匀,会导致总量没有到的情况下某些机器就开始限流。

因此仅靠单机维度去限制的话会无法精确地限制总体流量。而集群流控可以精确地控制整个集群的调用总量,结合单机限流兜底,可以更好地发挥流量控制的效果。

集群流控中共有两种身份:

  • Token Client:集群流控客户端,用于向所属 Token Server 通信请求 token。集群限流服务端会返回给客户端结果,决定是否限流。
  • Token Server:即集群流控服务端,处理来自 Token Client 的请求,根据配置的集群规则判断是否应该发放 token(是否允许通过)。
    在这里插入图片描述

二、整体架构

在这里插入图片描述

三、Sentinel 集群限流

  1. 创建集群限流客户端
  2. 创建集群限流服务端
  3. 配置限流规则(Nacos配置中心)

整体架构如下:
在这里插入图片描述

3.1 集群限流客户端

项目结构
在这里插入图片描述

3.1.1 添加动态获取限流规则InitFunc

/**
 * 从nacos上动态获取限流规则
 * 注意:需通过 SPI 机制添加
 */
public class DataSourceInitFunc implements InitFunc {

    // token server 地址
    private final String CLUSTER_SENTINEL_HOST = "127.0.0.1";
    // token server 端口
    private final int CLUSTER_SERVER_PORT = 9999;
    // 请求超时时间
    private final int REQUEST_TIMEOUT = 20000;

    // dataId
    private final String APP_NAME = "token-server";

    // nacos远程服务地址
    private static final String NACOS_REMOTE_ADDRESS = "localhost:8848";
    // nacos groupId
    private static final String GROUP_ID = "sentinel-group";

    @Override
    public void init() throws Exception {
        // 加载集群信息
        loadClusterClientConfig();

        // 注册集群限流规则属性:故障转移方案,当token server不用时,直接从 动态限流规则配置中心获取限流规则
        registryClusterFlowRuleProperty();
    }

    private void loadClusterClientConfig() {
        // 设置 token server 集群信息
        ClusterClientConfigManager.applyNewAssignConfig(new ClusterClientAssignConfig()
                .setServerHost(CLUSTER_SENTINEL_HOST)
                .setServerPort(CLUSTER_SERVER_PORT));

        // 设置超时时间
        ClusterClientConfigManager.applyNewConfig(new ClusterClientConfig()
                .setRequestTimeout(REQUEST_TIMEOUT)
        );
    }

    private void registryClusterFlowRuleProperty() {
        ReadableDataSource<String, List<FlowRule>> readableDataSources = new NacosDataSource<List<FlowRule>>(
                NACOS_REMOTE_ADDRESS,
                GROUP_ID,
                APP_NAME,
                source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
                }));

        FlowRuleManager.register2Property(readableDataSources.getProperty());
    }
}

3.1.2 指定客户端角色

// 指定角色:表示当前的节点是集群客户端
ClusterStateManager.applyState(ClusterStateManager.CLUSTER_CLIENT);

在这里插入图片描述

3.1.3 添加InitFunc SPI

在这里插入图片描述

创建文件:META-INF\services\com.alibaba.csp.sentinel.init.InitFunc

文件内容:

com.tortoise.tokenclient.DataSourceInitFunc

3.2 集群限流服务端

项目结构
在这里插入图片描述

3.2.1 引入相关依赖

创建一个 Maven 项目,引入以下依赖。

<dependencies>
    <!--Sentinel server端依赖-->
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-cluster-server-default</artifactId>
        <version>1.8.4</version>
    </dependency>
    <!--Sentinel 限流规则数据源-->
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-datasource-nacos</artifactId>
        <version>1.8.4</version>
    </dependency>
</dependencies>

3.2.2 创建 SentinelTokenServer

public class SentinelTokenServer {
    private static final String APP_NAME = "sentinel-token-server";

    public static void main(String[] args) throws Exception {
        ClusterTokenServer tokenServer = new SentinelDefaultTokenServer();

        ClusterServerConfigManager.loadGlobalTransportConfig(new ServerTransportConfig()
                .setIdleSeconds(600)
                .setPort(9999));
        ClusterServerConfigManager.loadServerNamespaceSet(Collections.singleton(SentinelTokenServer.APP_NAME));

        // Start the server.
        tokenServer.start();
    }
}

3.2.3 添加动态获取限流规则InitFunc

/**
 * 从nacos上动态获取限流规则
 * 注意:需通过 SPI 机制添加
 */
public class DataSourceInitFunc implements InitFunc {

    // nacos远程服务地址
    private static final String NACOS_REMOTE_ADDRESS = "localhost:8848";
    // nacos groupId
    private static final String GROUP_ID = "sentinel-group";

    @Override
    public void init() throws Exception {
        ClusterFlowRuleManager.setPropertySupplier(dataId -> {
            ReadableDataSource<String, List<FlowRule>> readableDataSources = new NacosDataSource<List<FlowRule>>(
                    NACOS_REMOTE_ADDRESS,
                    GROUP_ID,
                    dataId,
                    source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
                    }));
            return readableDataSources.getProperty();
        });
    }
}

3.2.4 添加InitFunc SPI

在这里插入图片描述

创建文件:META-INF\services\com.alibaba.csp.sentinel.init.InitFunc

文件内容:

com.tortoise.tokenserver.DataSourceInitFunc

3.3 Nacos配置限流规则

在Nacos创建对应的配置,添加JSON格式内容如下:

[
    {
        "resource": "resource-name",
        "grade": 1,
        "count": 100,
        "clusterMode": true,
        "clusterConfig": {
            "flowId": 1,
            "thresholdType": 1,
            "fallbackToLocalWhenFail": true
        }
    }
]

四、集群流控规则

FlowRule 添加了两个字段用于集群限流相关配置:

private boolean clusterMode; // 标识是否为集群限流配置
private ClusterFlowConfig clusterConfig; // 集群限流相关配置项

其中 用一个专门的 ClusterFlowConfig 代表集群限流相关配置项,以与现有规则配置项分开:

// (必需)全局唯一的规则 ID,由集群限流管控端分配.
private Long flowId;

// 阈值模式,默认(0)为单机均摊,1 为全局阈值.
private int thresholdType = ClusterRuleConstant.FLOW_THRESHOLD_AVG_LOCAL;

private int strategy = ClusterRuleConstant.FLOW_CLUSTER_STRATEGY_NORMAL;

// 在 client 连接失败或通信失败时,是否退化到本地的限流模式
private boolean fallbackToLocalWhenFail = true;
  • flowId 代表全局唯一的规则 ID,Sentinel 集群限流服务端通过此 ID 来区分各个规则,因此务必保持全局唯一。一般 flowId 由统一的管控端进行分配,或写入至 DB 时生成。
  • thresholdType 代表集群限流阈值模式。其中单机均摊模式下配置的阈值等同于单机能够承受的限额,token server 会根据客户端对应的 namespace(默认为 project.name 定义的应用名)下的连接数来计算总的阈值(比如独立模式下有 3 个 client 连接到了 token server,然后配的单机均摊阈值为 10,则计算出的集群总量就为 30);而全局模式下配置的阈值等同于整个集群的总阈值。

ParamFlowRule 热点参数限流相关的集群配置与 FlowRule 相似。

参考文献:https://sentinelguard.io/zh-cn/docs/introduction.html

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值