手机版

基于的分布式系统限流元件实例详解 网

时间:2021-08-31 来源:互联网 编辑:宝哥软件园 浏览:

前言

在互联网应用中,流量峰值很常见。在处理洪峰时,一般的处理方式是排队和限流,可以直接有效地保护系统,防止系统被炸。此外,通过限流技术,整个系统可以运行得更平稳。今天给大家分享一下限流算法和C#版本的组件。

1.令牌桶算法:

令牌桶算法的基本流程如下:

如果用户配置的平均发送速率为r,则每1/r秒将向桶中添加一个令牌。假设桶最多可以存储和发行B代币。当桶中的令牌达到上限时,丢弃令牌。当请求到达时,首先进入令牌桶获取令牌,然后处理请求。如果桶中没有令牌,排队或丢弃请求的过程包括三个阶段:生成令牌、消费令牌和判断数据包是否通过。涉及两个参数:令牌生成速率和令牌桶大小。这个过程的具体工作如下。

生成令牌:定期以固定速率向令牌桶中添加令牌,桶中的令牌不断增加。如果桶中的令牌数量已经达到上限,则丢弃冗余令牌。消费令牌:业务程序根据具体业务情况消费桶中的令牌。一旦消费,令牌桶中的令牌将减少1。通过判断:判断令牌桶中是否有有效的令牌。如果桶内代币数量能够满足需求,继续业务处理;否则,暂停业务并等待令牌。下面是C#的一个实现

类令牌桶限制服务: ILimitingService { private limited queue object limited queue=null;私有cancelToken源cancelToken私有任务任务=空;private int maxTPSprivate int LimitSize私有对象lckObj=new object();公共令牌桶限制服务(int maxTPS,int LimitSize){ this。LimitSize=LimitSizethis.maxTPS=maxTPSif(this。LimitSize=0)这一点。LimitSize=100如果(这个。maxtps=0)这一点。maxtps=1;受限队列=新的受限queue object(LimitSize);for(int I=0;我限制大小;i ) { limitedQueue .入队(新对象());} cancelToken=new cancellatitoken source();任务=任务。工厂。开始新(新操作(令牌流程),取消令牌。令牌);} ///摘要///定时消息令牌////summary private void token process(){ int sleep=1000/maxTPS;if(sleep==0)sleep=1;日期时间开始=日期时间。现在;while (cancelToken .令牌。iscancelingrequested==false){ 0尝试{锁定(lckObj){有限队列} .入队(新对象());} } catch { }最后{ if (DateTime .现在-开始时间跨度来自.毫秒(睡眠)){ int newSleep=sleep-(int)(DateTime .现在开始)。总数毫秒;如果(新leep 1)线程。睡眠(newSleep-1);//做一下时间上的补偿}开始时间=日期时间.现在;} } } public void Dispose(){ cancelToken .取消();} ///摘要///请求令牌////summary ///returnstrue:获取成功,假:获取失败/返回公共bool Request(){ if(limited queue)} .计数=0)返回假锁(lckObj) { if (limitedQueue).计数=0)返回错误的对象数据=limitedQueue .出列();如果(数据==null)返回false}返回真实} }公共接口ilimitingservice : idisposable {///summary///申请流量处理////summary ///returnstrue:获取成功,假:获取失败/返回bool Request();}公共类有限工厂{///summary///创建限流服务对象////summary///param name=' LimitingType '限流模型/param ///param name='maxQPS '最大QPS/参数///参数名称='limitSize '最大可用票据数/param公共静态ILimitingService Build(限制类型限制类型=限制类型.TokenBucket,int maxQPS=100,int LimitSize=100){ switch(limiting type){ case limiting type .令牌桶:默认值:返回新的令牌桶限制服务(maxQPS,LimitSize);案例限制类型泄漏桶:返回新的leakagebucket tllimingservice(Maxqps,LimitSize);} } } ///摘要///限流模式////摘要公共枚举限制类型{令牌桶,//令牌桶模式LeakageBucket//漏桶模式}公共类Limited QueueT : QueueT { private int limit=0;公共常量字符串QueueFulled=' TTP-流线化-1001 ';public int Limit { get { return Limit;}设置{ limit=value} }公共受限队列(): this(0){ }公共受限队列(int limit): base(limit){ this .极限=极限;}公共新布尔入队项{ if(0)限制此。计数=这个limit){ return false;}基地。入队(项);返回真;} }调用方法:

var service=LimitingFactory .构建(限制类型. TokenBucket,500,200);while (true){ var result=service .request();//如果返回没错,说明可以进行业务处理,否则需要继续等待if (result) { //业务处理.} else Thread .睡眠(1);}二、漏桶算法

声明一个固定容量的桶,每接受到一个请求向桶中添加一个令牌,当令牌桶达到上线后请求丢弃或等待,具体算法如下:

创建一个固定容量的漏桶,请求到达时向漏桶添加一个令牌如果请求添加令牌不成功,请求丢弃或等待另一个线程以固定的速率消费桶里的令牌工作过程也包括3个阶段:产生令牌、消耗令牌和判断数据包是否通过。其中涉及到2个参数:令牌自动消费的速率和令牌桶的大小,个过程的具体工作如下。

产生令牌:业务程序根据具体业务情况申请令牌。申请一次,令牌桶令牌加一。如果桶中令牌数已到达上限,则挂起业务后等待令牌。消费令牌:周期性的以固定速率消费令牌桶中令牌,桶中的令牌不断较少。判断是否通过:判断是否已有令牌桶是否存在有效令牌,当桶中的令牌数量可以满足需求时,则继续业务处理,否则将挂起业务,等待令牌C#。的一个实现方式:

class leakagebucket tllimitingservice : ILimitingService { private limited queue object limited queue=null;私有cancelToken源cancelToken私有任务任务=空;private int maxTPSprivate int LimitSize私有对象lckObj=new object();public leakagebucket tllimingservice(int MaxTPs,int LimitSize){ this。LimitSize=LimitSizethis.maxTPS=maxTPSif(this。LimitSize=0)这一点。LimitSize=100如果(这个。maxtps=0)这一点。maxtps=1;受限队列=新的受限queue object(LimitSize);cancelToken=new cancellatitoken source();任务=任务。工厂。开始新(新操作(令牌流程),取消令牌。令牌);} private void token process(){ int sleep=1000/MaxTPs;if(sleep==0)sleep=1;日期时间开始=日期时间。现在;while (cancelToken .令牌。iscancelingrequested==false){ try { if(有限队列)} .计数0){锁定(lckObj){ if(有限队列)} .计数0)限制队列。出列();} } } catch { }最后{ if (DateTime .现在-开始时间跨度来自.毫秒(睡眠)){ int newSleep=sleep-(int)(DateTime .现在开始)。总数毫秒;如果(新leep 1)线程。睡眠(newSleep-1);//做一下时间上的补偿}开始时间=日期时间.现在;} } } public void Dispose(){ cancelToken .取消();}公共bool Request(){ if(limited queue)} .Count=limitSize)返回假锁(lckObj) { if (limitedQueue).Count=limitSize)返回错误的返回限制队列。入队(新对象());} } }调用方法:

var service=LimitingFactory .构建(限制类型LeakageBucket,500,200);while (true){ var result=service .request();//如果返回没错,说明可以进行业务处理,否则需要继续等待if (result) { //业务处理.} else Thread .睡眠(1);}两类限流算法虽然非常相似,但是还是有些区别的,供大家参考!

漏桶算法能够强行限制数据的传输速率。在某些情况下,漏桶算法不能够有效地使用网络资源。因为漏桶的漏出速率是固定的。

令牌桶算法能够在限制数据的平均传输速率的同时还允许某种程度的突发传输。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

版权声明:基于的分布式系统限流元件实例详解 网是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。