暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

简析令牌桶算法原理及实现

分布式存储技术进阶 2019-05-24
1263

在网络中传输数据时,为了防止网络拥塞,需限制流出网络的流量,使流量以比较均匀的速度向外发送,令牌桶算法就实现了这个功能, 可控制发送到网络上数据的数目,并允许突发数据的发送。令牌桶算法是网络流量整形(Traffic Shaping)和速率限制(Rate Limiting)中最常使用的一种算法。


1

什么叫令牌

从名字上看令牌桶,顾名思义,大概就是一个装有令牌的桶吧,那么什么是令牌呢?在计算机的世界中,令牌也有令行禁止的意思,有令牌,则相当于得到了进行操作的授权,没有令牌,就什么都不能做。

2

令牌桶限速的原理

令牌桶这种控制机制,基于桶中令牌的个数,来实现流量大小的控制。大小固定的令牌桶可以以恒定的速度源源不断产生令牌,如果令牌不被消耗,或者被消耗的速度小于产生的速度,则令牌会持续增加,直到把桶填满。后面再产生令牌就会从桶中溢出,桶中可以保存的令牌数永远不可能超过桶的最大值。


当程序需要发送数据包时,需要消耗桶中的令牌,大小不同的数据包,消耗的令牌数量不一样。若桶中有足够令牌,则允许发送数据,同时桶中的令牌数相应减少对应数量。当令牌桶中令牌不足时,数据将不能被发送,只有等桶中产生了足够的新的令牌,才可以被发出。这样就可以限制数据的流量只能小于或者等于令牌生成的速度,达到限流的目的。





令牌桶算法简单的C语言实现范例:


#define LIMIT_MAX_TOKEN_IN_BUCKET 100

#define LIMIT_FLOW_SPEED 5 //per second 10

 

int token_bucket = 0;

time_t produce_time = 0;

 

void preduce_token()

{

    if(token_bucket == LIMIT_MAX_TOKEN_IN_BUCKET)

    {

        return;

    }

 

    int times = 0; //

 

    if(produce_time == 0)

    {

        produce_time = time(0);

        times = LIMIT_FLOW_SPEED;

    }

    else

    {

        time_t cur_time = time(0);

        times = (cur_time - produce_time) * LIMIT_FLOW_SPEED;

        if(times > 0)

        {

            produce_time = cur_time;

        }

    }

 

    token_bucket = token_bucket + times;

    if(token_bucket > LIMIT_MAX_TOKEN_IN_BUCKET)

    {

        token_bucket = LIMIT_MAX_TOKEN_IN_BUCKET;

    }

}

 

int cunsume_token(int datasize)

{

    //产生令牌

    preduce_token();

 

    //若当前令牌桶中令牌不足,则不能发送数据

    if((token_bucket <= 0) || (token_bucket < datasize))

    {

        return -1;

    }

 

    //消耗相应数量的令牌

    token_bucket -= datasize;

    return 0;

}




令牌桶算法实现的其他项目参考:


Java实现参考代码:

https://www.cnblogs.com/googlemeoften/p/6020718.html


Python实现参考:

https://www.jb51.net/article/136823.htm


Go语言实现参考:

https://github.com/juju/ratelimit


文章转载自分布式存储技术进阶,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论