多租户系统中如何实现分别限流

简介: 多租户系统中如何实现分别限流

多租户系统中如何实现分别限流


限流是后端服务开发中经常要集成的一个功能,对于防范系统因压力过大导致崩溃特别有用。在多租户系统中,限流对于限制单个租户使用的资源量也特别有用,这篇文章就来一探究竟。


问题


对于一个多租户系统,某些租户如果使用了过多的资源,很可能会对其它租户造成影响。比如对于某个资源的查询,系统的最高容量是300qps,假设正常情况下租户的查询水位都在10qps,此时可以同时为30个租户服务;突然某个租户的查询水位上升到100qps,如果系统没有限流,系统会变慢甚至可能崩溃,如果系统有限流,所有的租户都可能受到限流的影响。

租户的查询水位突然暴涨可能是正常业务,也可能是恶意攻击,不过无论哪种情况对其它租户来说都是不公平的。这时候就可以对不同的租户分别限流,下面就来看一下如何解决。


原理


下面这张图演示了对多租户系统进行限流的原理。


1689126077557.png



租户A、B、C分别发起服务请求,服务中首先对用户身份进行鉴别,身份验证通过的进入限流检查环节,对每个租户分别进行限流检查,如果未达到限流阈值,则可以通过进入下一步,如果达到了限流阈值,则终止处理并返回错误给租户。

实现

如果你已经看懂了原理,相信你完全有能力写出对应的限流控制逻辑。不过为了研发效率,还是应该尽可能重用现有的组件,这里使用 FireflySoft.RateLimit 来实现这一逻辑,演示代码是以ASP.NET Core为基础的,你也可以在任何其它.NET网络服务框架中使用,甚至自己手写的专用处理程序。

安装Nuget包

使用包管理器控制台:


Install-Package FireflySoft.RateLimit.AspNetCore

或者使用 .NET CLI:

dotnet add package FireflySoft.RateLimit.AspNetCore

或者直接添加到项目文件中:

<ItemGroup>
<PackageReference Include="FireflySoft.RateLimit.AspNetCore" Version="2.*" />
</ItemGroup>


使用中间件


在Startup.cs中注册限流服务并使用限流中间件。


public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddRateLimit(new InProcessFixedWindowAlgorithm(
        new[] {
            new FixedWindowRule()
            {
                Id = "1",
                ExtractTarget = context =>
                {
                    // 这里假设限流的目标是租户的用户Id,它是从HTTP Header中传递过来的
                    return (context as HttpContext).Request.GetTypedHeaders().Get<string>("userId");
                },
                CheckRuleMatching = context =>
                {
                    // 假设只对 /Weather/GetToday 这个接口请求进行限流
                    var path = (context as HttpContext).Request.Path.Value;
                    if(path == "/Weather/GetToday"){
                        return true;
                    }
                    return false;
                },
                Name="多租户限流",
                LimitNumber=10, // 限流阈值
                StatWindow=TimeSpan.FromSeconds(1), //限流的时间窗口,这里是1秒
                StartTimeType=StartTimeType.FromNaturalPeriodBeign
            }
        })
    );
    ...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    ...
    app.UseRateLimit();
    ...
}

搞定这两步,多租户分别限流功能就可以正常运转了。

这里对所有租户都使用了相同的限流阈值,如果租户有特权租户和普通租户的区别,则可以在上边的限流规则中分别为特权租户和普通租户定义不同的规则就可以了,具体可以参考这篇文章:ASP.NET Core中如何对不同类型的用户进行区别限流


其它技术问题


注意这里使用的限流算法是进程内固定窗口限流,如果你需要在分布式环境下统一计数限流,则可以使用 FireflySoft.RateLimit 自带的Redis固定窗口限流算法,不过你需要先有一个Redis服务。

固定窗口算法比较刚性,实际情况下,请求很可能是不均匀的,一会多一会少,刚性算法很难设置一个合理的限流阈值。如果你想要允许一定的突发流量,则可以使用滑动窗口、漏桶、令牌桶等算法,FireflySoft.RateLimit 中已经集成了这些算法,直接使用即可。

如果系统的服务能力增强了,现在允许一个租户每秒发起20次请求,则需要调整规则,FireflySoft.RateLimit底层是支持动态调整规则的,具体可以看这篇文章:.NET6运行时动态更新限流阈值

好了,以上就是本文的主要内容了。


相关文章
|
SpringCloudAlibaba 监控 Dubbo
SpringCloudAlibaba篇(三)整合Sentinel(限流、流量整形、熔断降级、系统负载保护、热点防护,分布式服务架构的高可用流量防护组件)
SpringCloudAlibaba篇(三)整合Sentinel(限流、流量整形、熔断降级、系统负载保护、热点防护,分布式服务架构的高可用流量防护组件)
SpringCloudAlibaba篇(三)整合Sentinel(限流、流量整形、熔断降级、系统负载保护、热点防护,分布式服务架构的高可用流量防护组件)
|
3月前
|
数据库 缓存 中间件
降级概述
【8月更文挑战第18天】
45 0
|
4月前
|
存储 缓存 分布式计算
高并发架构设计三大利器:缓存、限流和降级问题之缓存的应对策略问题如何解决
高并发架构设计三大利器:缓存、限流和降级问题之缓存的应对策略问题如何解决
|
4月前
|
监控 算法 Java
高并发架构设计三大利器:缓存、限流和降级问题之配置Sentinel的流量控制规则问题如何解决
高并发架构设计三大利器:缓存、限流和降级问题之配置Sentinel的流量控制规则问题如何解决
|
4月前
|
开发者 Sentinel 微服务
高并发架构设计三大利器:缓存、限流和降级问题之降级策略中的有限状态机的三种状态切换的问题如何解决
高并发架构设计三大利器:缓存、限流和降级问题之降级策略中的有限状态机的三种状态切换的问题如何解决
|
4月前
|
应用服务中间件 nginx 缓存
高并发架构设计三大利器:缓存、限流和降级问题之Nginx作为前置网关进行限流问题如何解决
高并发架构设计三大利器:缓存、限流和降级问题之Nginx作为前置网关进行限流问题如何解决
|
6月前
|
存储 缓存 算法
高并发架构设计三大利器:缓存、限流和降级
软件系统有三个追求:高性能、高并发、高可用,俗称三高。本篇讨论高并发,从高并发是什么到高并发应对的策略、缓存、限流、降级等。
191 1
|
存储 SpringCloudAlibaba 算法
系统高可用(一):限流
限流是对某一时间窗口内的请求数进行限制,保持系统的可用性和稳定性,防止因流量暴增而导致的系统运行缓慢或宕机
180 0
系统高可用(一):限流
|
6月前
|
监控 应用服务中间件 测试技术
4种典型限流实践保障应用高可用
大家好,我叫黄博文,花名延枚,目前负责云效旗下产品Flow流水线的设计和开发。在微服务架构下,服务越来越多,服务之间的调用也会越来越复杂。如何保障服务的高可用性就成为了一个挑战。之前我参与过的某个产品就曾出过故障,原因是某个API调用突然间增加了数十倍,导致服务负载过高,影响了用户使用。如果当时能够...
199 0
4种典型限流实践保障应用高可用