分布式场景下流量控制方案

1 常用限流方式

2 容器限流示例: Nginx限流

2.1 控制速率: 

2.2 控制并发数

3服务端限流

3.1 时间窗口算法

时间窗口算法又分为固定时间窗口和滑动时间窗口。
固定时间窗口是指固定时间段内, 使用计数器记录这段时间内接收的请求, 每接收一次请求就让计数器的值加一, 当计数器的值大于请求阈值时, 开始限流. 这个时间段结束后, 重新初始化计数器, 对新的时间窗口进行监控。
固定时间窗口存在临界突变的问题, 所谓临界突变, 是指在上一个时间段的最后时期和下一个时间段的开始时期突然涌入大量流量, 其结果是在各自时间段内流量控制产生效果, 但是在短时间内服务器会收到2倍于阈值数量的请求, 进而导致服务宕机, 如下图所示。

滑动时间窗口为固定窗口的改良版,解决了固定窗口在窗口切换时会受到两倍于阈值数量的请求,滑动窗口在固定窗口的基础上,将一个窗口分为若干个等份的小窗口,每个小窗口对应不同的时间点,拥有独立的计数器,当请求的时间点大于当前窗口的最大时间点时,则将窗口向前平移一个小窗口(将第一个小窗口的数据舍弃,第二个小窗口变成第一个小窗口,当前请求放在最后一个小窗口),整个窗口的所有请求数相加不能大于阀值。滑动时间窗口演示如下图:

3.1.1 基于Redis实现滑动时间窗口算法

Redis提供如下命令, 使用这几个命令可以方便快捷的实现滑动时间窗口算法进行限流

  • ZADD key score member: 用于将一个或多个成员元素及其分数值加入到有序集当中
  • ZREMRANGEBYSCORE key min max: 用于移除有序集中,指定分数(score)区间内的所有成员
  • ZCARD key: 用于计算集合中元素的数量

lua代码如下:

local time = redis.call('TIME')
local cur_timestamp = time[1]*1000+time[2]/1000
local period = tonumber(ARGV[1])
local maxCount = tonumber(ARGV[2])

redis.call('ZADD', KEYS[1], cur_timestamp, cur_timestamp)
redis.call('ZREMRANGEBYSCORE', KEYS[1], 0, cur_timestamp - period*1000)

redis.call('EXPIRE', KEYS[1], period)

local result
result = redis.call('ZCARD', KEYS[1])

if result > maxCount then
    redis.call("ZREM", KEYS[1], cur_timestamp)
    return 0
else
    return 1
end

java调用lua脚本代码如下:

public boolean slide(String key, int period, int maxCount) {
        final DefaultRedisScript<Long> defaultRedisScript = new DefaultRedisScript<>();
        defaultRedisScript.setResultType(Long.class);
        defaultRedisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/flowdemo/slide.lua")));

        ImmutableList<String> keys = ImmutableList.of(key);
        Object[] args = {period, maxCount};

        long result = businessRedisClient.execute(defaultRedisScript, keys, args);

        return result == 1;
    }

3.2 漏桶算法

漏桶作为计量工具时,可以用于流量整形(Traffic Shaping)和流量控制(TrafficPolicing)。

漏桶算法的描述如下:

  • 一个固定容量N的漏桶,按照常量固定速率V流出水滴;
  • 如果桶是空的,则不需流出水滴;
  • 可以以任意速率流入水滴到漏桶;
  • 如果流入水滴超出了桶的容量,则流入的水滴溢出了(被丢弃),而漏桶容量是不变的。

漏桶算法示意图如下:

3.3 令牌桶算法

令牌桶算法是一个存放固定容量令牌的桶,按照固定速率往桶里添加令牌。令牌桶算法的描述如下:

  • 假设限制2r/s,则按照500毫秒的固定速率往桶中添加令牌;
  • 桶中最多存放N个令牌,当桶满时,新添加的令牌被丢弃或拒绝;
  • 当一个请求到达,将从桶中删除m个令牌,接着处理请求;
  • 如果桶中的令牌不足m个,则不会删除令牌,且该请求将被限流(要么丢弃,要么缓冲区等待)。

令牌桶算法示意图如下:

3.4 基于Redis实现漏桶/令牌桶算法

漏桶/令牌桶算法是互逆的算法, 重点是控制速率, 漏桶是控制流出速率, 令牌桶是控制产生令牌的速率

Redis-Cell提供原子性的限流功能,并允许突发流量,可以很方便的应用于分布式环境中

下图是cli.throttle命令的解析图:

通过如下lua代码, 可以实现速率控制:

local key = KEYS[1]
local capacity = tonumber(ARGV[1])
local operations = tonumber(ARGV[2])
local period = tonumber(ARGV[3])
return redis.call('CL.THROTTLE',key,capacity,operations,period,1)

如果将速率用于控制流量的流出速度, 就可以实现漏桶算法:

如果将速率用于控制令牌的生成速度, 就可以实现令牌桶算法:
1: 是否成功,0:成功,1:拒绝
2: 令牌桶的容量,大小为初始值+1
3: 当前令牌桶中可用的令牌
4: 若请求被拒绝,这个值表示多久后才令牌桶中会重新添加令牌,单位:秒,可以作为重试时间
5: 表示多久后令牌桶中的令牌会存满

4 分布式流控组件: Sentinel

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。

Sentinel 的主要工作机制如下:

对主流框架提供适配或者显示的 API,来定义需要保护的资源,并提供设施对资源进行实时统计和调用链路分析。
根据预设的规则,结合对资源的实时统计信息,对流量进行控制。同时,Sentinel 提供开放的接口,方便您定义及改变规则。
Sentinel 提供实时的监控系统,方便您快速了解目前系统的状态。

Sentinel提供了非常完善的官方文档,地址如下:
Sentinel官方wiki: https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E9%A1%B5

4.1 Sentinel单机限流

Sentinel中主要概念是资源和规则,对于单机服务,只要设置了资源对应的限流规则,就可以对资源进行相应的保护
java代码实现如下:

public static void main(String[] args) {
        // 配置规则
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        // 设置资源名称
        rule.setResource("key");
        // QPS 不得超出 1
        rule.setCount(1);
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule.setLimitApp("default");
        rules.add(rule);
        // 加载规则
        FlowRuleManager.loadRules(rules);
        // 下面开始运行被限流作用域保护的代码
        while (true) {
            Entry entry = null;
            try {
                entry = SphU.entry("key");
                System.out.println("hello world");
            } catch (BlockException e) {
                System.out.println("blocked");
            } finally {
                if (entry != null) {
                    entry.exit();
                }
            }
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {}
        }
    }

上诉代码运行结果如下:

4.2 Sentinel集群限流

集群限流需要一个配置中心,Sentinel官方提供了sentinel-dashboard项目作为集群限流的配置中心, 官方称其为Token-server。并且Sentinel还提供了多种客户端demo,只需要下载项目代码,即可体验Token-server完整演示。

项目代码下载地址为: git@github.com:alibaba/Sentinel.git

下图是Sentinel官方提供的demo:

Sentinel集群限流演示(客户端以spring-webmvc为例):

1.启动sentinel-dashboard项目

2.启动spring-webmvc项目(需在启动脚本添加参数:

-Dcsp.sentinel.dashboard.server=127.0.0.1:8080

-Dproject.name=sentinel-demo-spring-webmvc):

控制台应用列表展示:

控制台簇点链路页面展示:

控制台添加流控规则页面展示:

控制台试试监控页面展示:

作者:邓杰
链接:移动云开发者社区
来源:移动云官网开发者社区

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 基于分布式文件系统的SDN控制器是一种新型的SDN控制器架构,它将分布式文件系统与SDN控制器相结合,旨在提高SDN控制器的可靠性、可扩展性和容错性。 传统的SDN控制器架构通常采用集中式控制器,并且所有的控制器都运行在同一个物理服务器上。这种架构存在单点故障和性能瓶颈等问题。而基于分布式文件系统的SDN控制器将控制器分布在不同的服务器上,并通过分布式文件系统实现控制器之间的信息共享和协调。 具体来说,基于分布式文件系统的SDN控制器架构包括以下几个关键组件: 1. 分布式文件系统:用于存储所有控制器的状态信息和SDN网络拓扑信息,确保所有控制器可以共享和访问这些信息。 2. 控制器集群:由多个控制器组成,每个控制器都运行在不同的服务器上,通过分布式文件系统实现状态信息和拓扑信息的共享和协调。 3. 控制器管理器:用于管理控制器集群,包括控制器的启动、关闭、故障恢复等操作。 4. SDN应用程序接口:用于与SDN交换机进行通信,实现网络控制和管理功能。 基于分布式文件系统的SDN控制器架构具有以下优点: 1. 可靠性高:控制器集群可以容忍单个服务器的故障,保证SDN网络的可靠性和稳定性。 2. 可扩展性好:可以动态添加或删除控制器,以适应不同规模和复杂度的SDN网络。 3. 容错性强:控制器集群可以自动检测和恢复故障,确保SDN网络的连续性和正确性。 总而言之,基于分布式文件系统的SDN控制器是一种新型的SDN控制器架构,它能够提高SDN网络的可靠性、可扩展性和容错性,具有广阔的应用前景。 ### 回答2: 基于分布式文件系统的SDN控制器是一种结合分布式文件系统和软件定义网络(SDN)技术的控制器。SDN控制器是SDN网络的大脑,负责网络流量管理、策略制定和路由控制等任务。而分布式文件系统是将存储资源分散在不同节点上,使文件能够并行存取的一种技术。 基于分布式文件系统的SDN控制器可以提供以下优势和功能: 1. 高可靠性与可扩展性:通过将存储资源分布在不同节点上,可以实现数据的冗余和备份,提高系统的可靠性。同时,分布式文件系统还具有良好的可扩展性,可以根据实际需求灵活添加新的节点。 2. 数据共享与协作:分布式文件系统可以实现不同节点之间的数据共享和协作。在SDN控制器中,各个节点可以通过共享文件系统中的数据,共同进行网络流量管理和决策制定,提高整个网络的性能和效率。 3. 数据一致性与同步:分布式文件系统具备数据一致性和同步的机制,确保不同节点上的数据始终保持一致。这对于SDN控制器来说非常重要,因为控制器需要维护一个全局的网络状态视图,保证所有节点的决策和操作都基于相同的数据。 4. 弹性与容错能力:由于分布式文件系统有多个节点,当其中一个节点发生故障或失效时,可以通过其他节点提供的数据进行恢复和容错,确保SDN控制器的正常运行。 总结起来,基于分布式文件系统的SDN控制器集成了分布式文件系统的高可靠性、可扩展性和数据共享等特点,使得控制器能够更加有效地管理和控制SDN网络。 ### 回答3: 基于分布式文件系统的SDN控制器是一种将分布式文件系统与软件定义网络(SDN)相结合的方案。SDN控制器是SDN网络中的核心组件,负责网络的管理和控制。而分布式文件系统是一种将文件分布在多个存储节点上的系统,通过数据复制和故障恢复来提高数据的可靠性和可用性。 基于分布式文件系统的SDN控制器的核心思想是将SDN控制器的配置和状态信息存储在分布式文件系统中,以实现控制器的高可用和容错性。当一个控制器节点出现故障时,其他节点可以接替其工作,并从分布式文件系统中获取最新的配置和状态信息。这种分布式的设计可以提高整个SDN网络的可靠性和可扩展性。 另外,分布式文件系统还可以用于存储SDN控制器生成的流表和路由策略等信息。SDN网络中的流表非常庞大,而且经常需要更新和调整。使用分布式文件系统可以将这些流表信息存储在多个节点上,并通过数据复制和故障恢复保证数据的完整性和可靠性。 基于分布式文件系统的SDN控制器还可以支持多租户的场景。多租户是指将一个物理网络划分为多个逻辑网络,每个租户拥有自己的网络拓扑和控制器。使用分布式文件系统可以为每个租户分配独立的存储空间,保证租户之间的互相隔离和数据的安全性。 综上所述,基于分布式文件系统的SDN控制器通过将控制器的配置和状态信息存储在分布式文件系统中,实现了控制器的高可用和容错性,并且支持了大规模网络和多租户场景。这种设计可以提高SDN网络的可靠性、可扩展性和安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值