redis 在業務層的使用之分佈式限頻

    限頻通常反向代理都會有自帶的一些設置參數,可是入口複雜的狀況下,想作分佈式限頻,僅僅使用分佈式反向代理的參數是徹底不夠用的,這裏使用redis 比較好實現,爲啥呢?還不是基於redis 的原子性!python

   使用redis 實現分佈式限頻,如何作呢?一個是原子計數,一個是按時間戳地板除。redis

   下面是一個簡單的python 封裝,用於演示基本原理:分佈式

#encoding=utf8
import redis
import time
import threading

host = "127.0.0.1"
port = "6379"
password = "123123"
db = 0

pool = redis.ConnectionPool(host=host, port=port, password=password, db=db)
rd = redis.StrictRedis(connection_pool=pool)


class Counter(object):
    def __init__(self, key, delta = 1):
        self.redis_client = rd
        self.delta = delta
        self.key = key

    def increment(self):
        t = int(time.time())
        sign = t / self.delta
        redis_key = self.key + '_' + str(sign)
        counter = self.redis_client.incr(redis_key)
        self.redis_client.expire(redis_key, 10 * self.delta)  # 控制時間,防止爆掉內存
        return counter

def add_task(item):
    c = Counter("test", 60) # key 爲test,計數週期爲60s
    threshold = 100
    for i in range(1000):
        time.sleep(0.2)
        x = c.increment()
        if x > threshold:
            print "over limit"
        else:
            print "thread:%s ,itme:%s" % (item, x)

if __name__ == '__main__':
    t1 = threading.Thread(target=add_task, args=(1,))
    t2 = threading.Thread(target=add_task, args=(2,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()

    封裝的要點是對當前時間地板除,參數key 爲要計數的key,delta 就是計數週期,redis 只負責計數,由業務邏輯負責閾值判斷。代理

相關文章
相關標籤/搜索