最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python實現(xiàn)常見限流算法的示例代碼

 更新時間:2024年03月12日 10:28:41   作者:shigen01  
在系統(tǒng)的穩(wěn)定性設計中,需要考慮到的就是限流,避免高并發(fā)環(huán)境下一下子把服務整垮了,本文為大家整理了一些Python實現(xiàn)的常見限流算法,希望對大家有所幫助

前提

本地的redis服務已經(jīng)啟動,mac用戶兩行命令即可:

 brew install redis && brew services start redis

完了之后,在代碼里寫上獲得redis連接的代碼:

 def get_redis_con():
     pool = redis.ConnectionPool(max_connections=4, decode_responses=True)
     return redis.Redis(connection_pool=pool)

其他配置參照官方文檔。

固定窗口

類似于把時間切分了,每個時間段只允許固定次的請求。

最直白的話語就是:我的接口1s只允許100次請求,多了我就拋異常。

 def fixed_window(user, action, time_zone=60, max_times=30):
     key = f'{action}'
     count = get_redis_con().get(key)
     if not count:
         count = 1
         get_redis_con().setex(key, time_zone, count)
     if int(count) < max_times:
         get_redis_con().incr(key)
         return True
     return False

代碼中加上了user,其實就是避免單個用戶的接口防刷。在之前的文章<如何優(yōu)雅的實現(xiàn)接口防刷>中,其實就是用的這種方法。

對應的話,其實也是有一些問題的。

最主要的一個缺點就是:流量不是平滑的,可能存在多個流量峰值導致服務間歇性的不可用。最直觀的感受是在窗口切換的時候,流量堆積導致的問題。

滑動窗口

描述的原理是:

  • 將時間劃分為細粒度的區(qū)間,每個區(qū)間維持一個計數(shù)器,每進入一個請求則將計數(shù)器加一;
  • 多個區(qū)間組成一個時間窗口,每流逝一個區(qū)間時間后,則拋棄最老的一個區(qū)間,納入新區(qū)間;
  • 若當前窗口的區(qū)間計數(shù)器總和超過設定的限制數(shù)量,則本窗口內(nèi)的后續(xù)請求都被丟棄。

可能還是有一些抽象,我們借用代碼來講解:

 def silde_window(user, action, time_zone=60, max_times=30):
     key = f'{action}'
     now_ts = time.time() * 1000
     # ms級時間戳,保證唯一
     value = now_ts
     # 時間窗口的左邊界
     old_ts = now_ts - time_zone * 1000
     # 記錄 {成員元素:分數(shù)值}
     mapping = {
         value: now_ts,
     }
     get_redis_con().zadd(key, mapping)
     # 刪除時間窗口之前的數(shù)據(jù)
     get_redis_con().zremrangebyscore(key, -1, old_ts)
     # 獲得窗口內(nèi)的行為數(shù)量
     count = get_redis_con().zcard(key)
     get_redis_con().expire(key, time_zone + 1)
     if not count or int(count) < max_times:
         return True
     return False

用到的數(shù)據(jù)結(jié)構是zset。這里的時間戳就是對應值的score。

這種方式可以應對流量的激增,但是流量的曲線還是不夠平滑。

漏桶算法

就類似于一個桶,請求先去填滿桶,填滿之后,其它的請求直接拒絕;同時,桶以一定的速率漏出,放行請求。

這種算法的速率是不支持動態(tài)調(diào)整的,對于系統(tǒng)資源的充分利用上還是存在問題的。

令牌桶算法

漏桶算法的主角是桶,令牌桶的主角是令牌。

 def pass_token_bucket(user, action, time_zone=60, max_times=30):
     key = f'{user}:{action}'
     # 令牌生成速度
     rate = max_times / time_zone
     capacity = max_times
     token_count = get_redis_con().hget(key, 'tokens')
     last_time = get_redis_con().hget(key, 'last_time')
     now = time.time()
     token_count = int(token_count) if token_count else capacity
     last_time = last_time if last_time else now
     # 經(jīng)過一段時間之后生成的令牌數(shù)量
     new_token_count = int((now - last_time) * rate)
     if new_token_count > 1:
         token_count += new_token_count
         if token_count > capacity:
             token_count = capacity
         last_time = time.time()
         get_redis_con().hset(key, 'last_time', last_time)
 ?
     if token_count >= 1:
         token_count -= 1
         get_redis_con().hset(key, 'tokens', token_count)
         return True
     return False

對于漏桶和令牌桶,算法的實現(xiàn)其實都大差不差。shigen在學習這個的時候,還有一點整混淆了。

最后,說一下如何驗證,使用到了python的多線程。

 executor = ThreadPoolExecutor(max_workers=4)
 APIS = ['/api/a', '/get/user/1', '/get/user/2', '/get/user/3']
 ?
 ?
 def task() -> bool:
     user = random.randint(1000, 1010)
     status = pass_token_bucket(user, random.choice(APIS))
     if not status:
         raise SystemError('{}被限制'.format(user))
     return status
   
   if __name__ == '__main__':
     jobs = [executor.submit(task) for _ in range(1000)]
     for job in jobs:
         print(job.result())

到此這篇關于Python實現(xiàn)常見限流算法的示例代碼的文章就介紹到這了,更多相關Python限流算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 使用Python+wxpy 找出微信里把你刪除的好友實例

    使用Python+wxpy 找出微信里把你刪除的好友實例

    今天小編就為大家分享一篇使用Python+wxpy 找出微信里把你刪除的好友實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-02-02
  • 圖文詳解Python中如何簡單地解決Microsoft?Visual?C++?14.0報錯

    圖文詳解Python中如何簡單地解決Microsoft?Visual?C++?14.0報錯

    有的時候安裝python依賴包的時候,報錯信息"Microsoft?visual?c++?14.0?is?required"的解決辦法,下面這篇文章主要給大家介紹了關于Python中如何簡單地解決Microsoft?Visual?C++?14.0報錯的相關資料,需要的朋友可以參考下
    2023-02-02
  • Python??inspect?模塊的簡單使用及常用方法

    Python??inspect?模塊的簡單使用及常用方法

    Python的inspect模塊是一個強大的內(nèi)省工具,允許開發(fā)者檢查(inspect)活動對象和源代碼,這篇文章主要介紹了Python?inspect?模塊的簡單使用及常用方法,需要的朋友可以參考下
    2024-03-03
  • Python 元類(中):攔截類的創(chuàng)建方法

    Python 元類(中):攔截類的創(chuàng)建方法

    這段文章介紹了Python中的元元類的概念及其應用法,通過自定義元元類可以攔截類類創(chuàng)建過程、自動注入屬性、校驗類定義、實現(xiàn)單例模式和插件自動注冊等功能,極大增強了類定義的靈活性與可控性,感興趣的朋友一起看看吧
    2026-05-05
  • 簡單介紹Python的第三方庫yaml

    簡單介紹Python的第三方庫yaml

    今天給大家?guī)淼氖顷P于Python的相關知識,文章圍繞著Python的第三方庫yaml展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • Python yield的用法實例分析

    Python yield的用法實例分析

    這篇文章主要介紹了Python yield的用法,結(jié)合實例形式分析了Python yield的基本功能、使用方法及操作注意事項,需要的朋友可以參考下
    2020-03-03
  • python json load json 數(shù)據(jù)后出現(xiàn)亂序的解決方案

    python json load json 數(shù)據(jù)后出現(xiàn)亂序的解決方案

    今天小編就為大家分享一篇python json load json 數(shù)據(jù)后出現(xiàn)亂序的解決方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-02-02
  • Python用K-means聚類算法進行客戶分群的實現(xiàn)

    Python用K-means聚類算法進行客戶分群的實現(xiàn)

    這篇文章主要介紹了Python用K-means聚類算法進行客戶分群的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • Python插入Elasticsearch操作方法解析

    Python插入Elasticsearch操作方法解析

    這篇文章主要介紹了Python插入Elasticsearch操作方法解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01
  • 創(chuàng)建Shapefile文件并寫入數(shù)據(jù)的例子

    創(chuàng)建Shapefile文件并寫入數(shù)據(jù)的例子

    今天小編就為大家分享一篇創(chuàng)建Shapefile文件并寫入數(shù)據(jù)的例子,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11

最新評論

大宁县| 平阴县| 美姑县| 囊谦县| 清苑县| 大港区| 涿州市| 楚雄市| 夹江县| 蕉岭县| 类乌齐县| 石楼县| 淳安县| 四平市| 安徽省| 太湖县| 当雄县| 临安市| 莆田市| 汕头市| 宁明县| 义乌市| 日喀则市| 夏津县| 恭城| 汝南县| 崇左市| 密山市| 五河县| 竹溪县| 东源县| 东明县| 威远县| 广丰县| 成武县| 长子县| 定州市| 久治县| 绍兴市| 马公市| 宣汉县|