中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何實現API接口限流

發布時間:2021-12-30 10:53:30 來源:億速云 閱讀:189 作者:小新 欄目:大數據

這篇文章主要介紹如何實現API接口限流,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!


同樣,在互聯網行業中,也存在這樣得場景,我們把它稱為——限流,為什么要限流呢,原因如下:

在系統上線初期,用戶量和訪問量不大得時候,一般部署幾臺應用服務器,數據庫做一個讀寫分離就基本上抗得住,但隨著時間的推移,業務的發展,用戶量和日活得增加,系統所承受的壓力越來越大,我么都知道,應用服務器擴容很方便,但數據庫擴容就有些麻煩,如果請求數據庫的量太大的話,或者遇到惡意攻擊,數據庫極有可能宕機,最后導致整個網站不可用。

為了避免這樣的事情發生,我們通常要限制住用戶的請求次數。對于合法的用戶,我們要限制單位時間內用戶調用接口的次數,對于惡意攻擊者,直接將他放入黑名單中。

我們通常用Redis中的zset數據結構來做限流。由于zset底層是用跳躍表存儲數據的,按score字段從小到大排序,我們可以把時間戳存入score字段。隨著時間的流逝,把每一次請求的時間戳存入score中,而member呢?隨便存儲什么無所謂啦,但不要存儲太大的數據。如下圖:

如何實現API接口限流

假如我們要求接口的調用一分鐘不能超過100次,那么圖中橙色矩形區域是一個時間段范圍內的時間窗口,矩形的有邊框是當前時間,它隨著時間的流逝一點一點向右移動,矩形左邊框是1min前,矩形的寬度就是1min。我們通過Redis的zcount命令很容易計算出這個時間范圍內的數據量,如果數據量超出100,說明用戶請求的太快了,應該進行限流的操作。下面來看一段簡單的代碼:

/**     * 基于zset限流     * @param key       redis key     * @param maxCount  指定時間內最大通過個數     * @param timeRange 時間窗范圍,單位:秒     * @return          是否可以繼續請求     */    public static  boolean rateLimiterByZset(String key,int maxCount,int timeRange){        try (Jedis jedis = jedisPool.getResource()) {            long currentTime = new Date().getTime();        //當前時間戳            long secondTime = currentTime-timeRange*1000;      //second秒前的時間戳            long memberCount = jedis.zcount(key,secondTime,currentTime);            if(memberCount >= maxCount){                return false;            }
           jedis.zadd(key,currentTime,currentTime+"");            //刪除時間框外的數據,因為它們已經沒有用了            jedis.zremrangeByScore(key,0,secondTime);        }        return true;    }

哈哈,就這么簡單。有一點要注意的是,請大家及時刪除時間框(也就是上圖中左邊框外)范圍外的數據,因為它們已經沒有用了,留著非常消耗內存資源。

大家會不會有這樣的疑問:對zset操作這么頻繁,會不會有性能上的問題呀?其實大家不必太擔心,畢竟Redis的數據結構都是經過精心設計的,性性能很高,大家可以參考小編的這篇文章,來學習Redis的數據結構。

從數據存儲角度分析Redis性能為何如此高

劉蒞,公眾號:向代碼致敬從數據存儲角度分析Redis性能為何如此高  

測試程序和輸出效果如下:

@Test    public void test1() throws Exception{        int i = 1;        while(true){            Thread.sleep(5);            boolean flag = RedisRateLimiter.rateLimiterByZset("keysss",10,1);            if(flag){                System.out.println("第"+i+"個請求成功");            }else{                System.out.println("第"+i+"個被限流");            }            i++;        }    }
第1個請求成功第2個請求成功第3個請求成功第4個請求成功第5個請求成功第6個請求成功第7個請求成功第8個請求成功第9個請求成功第10個請求成功第11個被限流第12個被限流...第42個被限流第43個被限流第44個請求成功第45個請求成功第46個請求成功第47個請求成功第48個請求成功第49個請求成功第50個請求成功第51個請求成功第52個請求成功第53個請求成功第54個被限流第55個被限流...

以上是“如何實現API接口限流”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

api
AI

丹阳市| 四子王旗| 塘沽区| 梁山县| 延长县| 井冈山市| 鸡泽县| 屯门区| 侯马市| 武鸣县| 襄垣县| 阿鲁科尔沁旗| 电白县| 湘阴县| 观塘区| 庆安县| 无锡市| 突泉县| 会宁县| 汤原县| 吉木萨尔县| 榆树市| 弥勒县| 怀仁县| 盖州市| 斗六市| 塔城市| 罗定市| 武威市| 崇明县| 衡阳市| 阿克陶县| 邳州市| 深水埗区| 芦山县| 鸡东县| 宣恩县| 德清县| 峡江县| 遂昌县| 镇沅|