<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    jinfeng_wang

    G-G-S,D-D-U!

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      400 Posts :: 0 Stories :: 296 Comments :: 0 Trackbacks
    http://www.tuicool.com/articles/ZvURvq2  


    摘要

    • 我們希望服務器能在請求流量的控制上有一定的自動控制能力;
    • 本文通過簡介令牌桶算法和討論算法的 redis 實現給出流量整形(traffic shaping)的示例,來介紹網絡流量整形。

    令牌桶算法

    • 令牌桶算法 (token bucket) 并不是網絡流量整形中的奇技淫巧,而是非常常用的算法,從百度百科上已經可以對它有一個概括的了解。對此算法的深入讀者可自行查閱研究,這里我通俗化的來解釋一下這個算法。

    • 在令牌桶算法中,每一個訪客都擁有一個獨立的“令牌桶”,在這個“令牌桶”里放了一些“令牌”,訪客每次來訪都會消耗“令牌桶”中的“令牌”,如果“令牌桶”空了,將會對訪客做特殊處理(如拒絕其繼續訪問以達到限流的目的)。

    • 問題一:訪客來訪是一個持續的過程,如果最初的“令牌”數目固定,“令牌桶”中的令牌會慢慢被消耗殆盡,這樣正常的訪客也將無法訪問—-所以我們需要以一個恒定的速率來向“令牌桶”中添加一定數量的“令牌”, 這樣就可以讓訪客持續的訪問。

    • 問題二:我們以一個恒定速率向“令牌桶”中添加“令牌”, 那么如果訪客一直沒來訪他的“令牌桶”豈不會累積大量“令牌”么?—-所以,我們設定“令牌桶”中“令牌”的最大數量,“令牌桶”滿了就不需要再去添加了。這解決了“令牌”累積的問題,也使它更像一個“桶”。

    • 如此,“令牌桶算法”中的重要的參數有:1. 給“令牌桶”添加“令牌”的速率(如果訪客以這個速率消耗令牌,將一直不會被限流); 2. “令牌桶”的容量(如果消耗令牌的速率大于添加令牌的速率,將消耗桶中的存貨,如果消耗速率過大,令牌會被消耗殆盡,訪客將被限流)。注意:一般情況下“令牌桶”最初的狀態是滿的。

    Redis

    • 作為優秀的內存數據庫,redis 可以幫助我們在應用層次快速響應。本文不過多贅述 redis 的優劣,你可以用 redis 做很多事情,在網絡流量整形方面,它是很好的實現方案, 下面我們來解析這樣一個方案。

    Show me the code

    • 說明:這是一段 Python 代碼,這段代碼來自 GitHub 用戶 justinfay 。為了使邏輯更清楚,我修改了代碼的部分內容和注釋,以下是修改后的代碼,我們用這段代碼來看令牌桶算法的 redis 實現。
    import redis from redis import WatchError import time  RATE = 0.1 # 令牌桶的最大容量 DEFAULT = 100 # redis key 的過期時間 TIMEOUT = 60 * 60  r = redis.Redis()  def token_bucket(tokens, key):      pipe = r.pipeline()     while 1:         try:             pipe.watch('%s:available' % key)             pipe.watch('%s:ts' % key)              current_ts = time.time()              # 獲取令牌桶中剩余令牌             old_tokens = pipe.get('%s:available' % key)             if old_tokens is None:                 current_tokens = DEFAULT             else:                 old_ts = pipe.get('%s:ts' % key)                 # 通過時間戳計算這段時間內應該添加多少令牌,如果桶滿,令牌數取桶滿數。                 current_tokens = float(old_tokens) + min(                     (current_ts - float(old_ts)) * RATE,                     DEFAULT - float(old_tokens)                 )             # 判斷剩余令牌是否足夠             if 0 <= tokens <= current_tokens:                 current_tokens -= tokens                 consumes = True             else:                 consumes = False              # 以下動作為更新 redis 中key的值,并跳出循環返回結果。             pipe.multi()             pipe.set('%s:available' % key, current_tokens)             pipe.expire('%s:available' % key, TIMEOUT)             pipe.set('%s:ts' % key, current_ts)             pipe.expire('%s:ts' % key, TIMEOUT)             pipe.execute()             break         except WatchError:             continue         finally:             pipe.reset()     return consumes  if __name__ == "__main__":     tokens = 5     key = '192.168.1.1'     if token_bucket(tokens, key):         print 'haz tokens'     else:         print 'cant haz tokens'

    需要說的幾點

    1. 這段代碼在網絡流量整形策略中起到什么作用?

    • 對訪客的一次訪問,我們通過以上代碼可以來判斷此次訪問是否超過了我們的限制,通過返回的判斷結果,我們將對此次訪問選擇正確的處理策略,比如你可以拒絕消耗完令牌的訪客進行訪問,從而控制他的訪問速率,從而達到網絡流量整形的目的。

    2. redis 在其中如何工作?

    • 對于每個獨立的訪客,redis 會為他建立兩個 key,一個 key 保存了剩余令牌的數量,另外一個 key 保存了最近一次訪問的時間戳。其中,最近一次訪問時間戳在新訪問到來時候用于計算時間間隔,從而計算在此時間間隔內應該向令牌桶中添加多少令牌,進而獲得當前令牌桶的剩余令牌數。

    3. redis pipe 起到什么作用?

    • 我們看到代碼中 while 循環,執行了 redis pipe 中的 watch 動作,這是對 redis 事務 的使用。 這使這里的算法能處理并發的來訪。在 redis 中,事務執行是對 redis key 的一個加鎖的操作,一個事務沒有執行完,別的動作將無法操作這個 key ,代碼中循環執行 watch 動作,就是去檢查當前 key 是否有未執行完畢的事務,只有所有事務都執行的時候才可能進入執行體,完成令牌判斷或者消耗。 —— 這樣避免了并發的訪問在 set redis key 時候的混亂。

    4. 如何調參

    • 代碼中 RATE 和 DEFAULT 為主要參數,分別代表每秒鐘消耗令牌的速率,和令牌桶的容量。通過調整這兩個參數來控制你想要的訪問速率。

    總結

    • 這是一個實用的方式來完成網絡流量整形,可以有效控制一些爆發式的流量訪問,使訪問更加平滑容易控制。
    posted on 2016-12-14 17:39 jinfeng_wang 閱讀(160) 評論(0)  編輯  收藏 所屬分類: 2016-REDIS
    主站蜘蛛池模板: 免费国产怡红院在线观看| 久久精品国产免费观看| 免费黄色一级毛片| 亚洲成aⅴ人片在线影院八| 91久久青青草原线免费| 亚洲成色在线影院| 99爱视频99爱在线观看免费| 欧洲亚洲国产清在高| 国产va在线观看免费| 久久精品国产亚洲AV高清热| 青青草无码免费一二三区| 亚洲美女中文字幕| 91成人免费观看网站| 亚洲人片在线观看天堂无码| 国产免费无遮挡精品视频| 一级女性全黄生活片免费看| 伊人久久亚洲综合| 免费人成视频在线观看网站| 亚洲狠狠ady亚洲精品大秀| 四虎成人免费大片在线| 黄色一级免费网站| 国产亚洲A∨片在线观看| 免费国产黄网站在线观看视频| 中中文字幕亚洲无线码| 四虎影视免费永久在线观看| 亚洲五月午夜免费在线视频| 国精无码欧精品亚洲一区| 久久WWW免费人成一看片| 亚洲国产AV一区二区三区四区| 亚洲精品国产自在久久| 久久福利青草精品资源站免费| 亚洲喷奶水中文字幕电影| 日韩在线免费电影| 在线免费观看伊人三级电影| 亚洲国产美女精品久久久久| 国产精品嫩草影院免费| 精品一区二区三区免费 | 亚洲av之男人的天堂网站| 亚洲美女视频免费| 美女免费精品高清毛片在线视| 亚洲AV永久无码精品一百度影院|