<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ### 漏桶 漏桶(Leaky Bucket)算法思路很簡單,水(請求)先進入到漏桶里,漏桶以一定的速度出水(接口有響應速率),當水流入速度過大會直接溢出(訪問頻率超過接口響應速率),然后就拒絕請求,可以看出漏桶算法能強行限制數據的傳輸速率.示意圖如下:![](https://mmbiz.qpic.cn/mmbiz_jpg/niaWWW4jIlibxibYHyPDX8KLjdEicAxgVdzvkGoIEX3icR4t6fiaJQ9pb6T5rvu0u5k6qhNqHyzibAJ6TcjHEhClIiadSQ/640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1) 具體代碼實現如下 ~~~ <?php class Funnel { private $capacity; private $leakingRate; private $leftQuote; private $leakingTs; public function __construct($capacity, $leakingRate) { $this->capacity = $capacity; //漏斗容量 $this->leakingRate = $leakingRate;//漏斗流水速率 $this->leftQuote = $capacity; //漏斗剩余空間 $this->leakingTs = time(); //上一次漏水時間 } public function makeSpace() { $now = time(); $deltaTs = $now-$this->leakingTs; //距離上一次漏水過去了多久 $deltaQuota = $deltaTs * $this->leakingRate; //可騰出的空間 if($deltaQuota < 1) { return; } $this->leftQuote += $deltaQuota; //增加剩余空間 $this->leakingTs = time(); //記錄漏水時間 if($this->leftQuota > $this->capacaty){ $this->leftQuote - $this->capacity; } } public function watering($quota) { $this->makeSpace(); //漏水操作 if($this->leftQuote >= $quota) { $this->leftQuote -= $quota; return true; } return false; } } $funnels = []; global $funnel; function isActionAllowed($userId, $action, $capacity, $leakingRate) { $key = sprintf("%s:%s", $userId, $action); $funnel = $GLOBALS['funnel'][$key] ?? ''; if (!$funnel) { $funnel = new Funnel($capacity, $leakingRate); $GLOBALS['funnel'][$key] = $funnel; } return $funnel->watering(1); } for ($i=0; $i<20; $i++){ var_dump(isActionAllowed("110", "reply", 15, 0.5)); //執行可以發現只有前15次是通過的 } ~~~ 核心邏輯就是makeSpace,在每次灌水前調用以觸發漏水,給漏斗騰出空間。funnels我們可以利用Redis中的hash結構來存儲對應字段,灌水時將字段取出進行邏輯運算后再存入hash結構中即可完成一次行為頻度的檢測。但這有個問題就是整個過程的原子性無法保證,意味著要用鎖來控制,但如果加鎖失敗,就要重試或者放棄,這回導致性能下降和影響用戶體驗,同時代碼復雜度也升高了,此時Redis提供了一個插件,Redis-Cell出現了。 ##### Redis-Cell Redis 4.0提供了一個限流Redis模塊,名稱為redis-cell,該模塊提供漏斗算法,并提供原子的限流指令。 該模塊只有一條指令cl.throttle,其參數和返回值比較復雜。 ~~~ > cl.throttle tom:reply 14 30 60 1 1) (integer) 0 # 0表示允許,1表示拒絕 2) (integer) 15 # 漏斗容量capacity 3) (integer) 14 # 漏斗剩余空間left_quota 4) (integer) -1 # 如果拒絕了,需要多長時間后再重試,單位秒 5) (integer) 2 # 多長時間后,漏斗完全空出來,單位秒 ~~~ 該指令意思為,允許用戶tom的reply行為的頻率為每60s最多30次,漏斗初始容量為15(因為是從0開始計數,到14為15個),默認每個行為占據的空間為1(可選參數)。如果被拒絕,取返回數組的第四個值進行sleep即可作為重試時間,也可以異步定時任務來重試。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看