<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Node+Redis進(jìn)行API速率限制的方法介紹

          共 3356字,需瀏覽 7分鐘

           ·

          2021-01-14 23:06


          來(lái)源 |?https://codeburst.io/api-rate-limiting-with-node-and-redis-95354259c768

          速率限制可以保護(hù)和提高基于API的服務(wù)的可用性。如果你正在與一個(gè)API對(duì)話,并收到HTTP 429 Too Many Requests的響應(yīng)狀態(tài)碼,說(shuō)明你已經(jīng)被速率限制了。這意味著你超出了給定時(shí)間內(nèi)允許的請(qǐng)求數(shù)量。你需要做的就是放慢腳步,稍等片刻,然后再試一次。

          為什么要速率限制?

          當(dāng)你考慮限制你自己的基于API的服務(wù)時(shí),你需要在用戶(hù)體驗(yàn)、安全性和性能之間進(jìn)行權(quán)衡。
          控制數(shù)據(jù)流的最常見(jiàn)原因是保持基于API的服務(wù)的可用性。但也有安全方面的好處,一次無(wú)意或有意的入站流量激增,就會(huì)占用寶貴的資源,影響其他用戶(hù)的可用性。
          通過(guò)控制傳入請(qǐng)求的速率,你可以:
          • 保障服務(wù)和資源不被“淹沒(méi)”。

          • 緩和暴力攻擊

          • 防止分布式拒絕服務(wù)(DDOS)攻擊

          如何實(shí)施限速?

          速率限制可以在客戶(hù)端級(jí)別,應(yīng)用程序級(jí)別,基礎(chǔ)架構(gòu)級(jí)別或介于兩者之間的任何位置實(shí)現(xiàn)。有幾種方法可以控制API服務(wù)的入站流量:
          • 按用戶(hù):跟蹤用戶(hù)使用API密鑰、訪問(wèn)令牌或IP地址進(jìn)行的調(diào)用

          • 按地理區(qū)域劃分:例如降低每個(gè)地理區(qū)域在一天的高峰時(shí)段的速率限制

          • 按服務(wù)器:如果你有多個(gè)服務(wù)器處理對(duì)API的不同調(diào)用,你可能會(huì)對(duì)訪問(wèn)更昂貴的資源實(shí)施更嚴(yán)格的速率限制。

          你可以使用這些速率限制中的任何一種(甚至組合使用)。
          無(wú)論你選擇如何實(shí)現(xiàn),速率限制的目標(biāo)都是建立一個(gè)檢查點(diǎn),該檢查點(diǎn)拒絕或通過(guò)訪問(wèn)你的資源的請(qǐng)求。許多編程語(yǔ)言和框架都有實(shí)現(xiàn)這一點(diǎn)的內(nèi)置功能或中間件,還有各種速率限制算法的選項(xiàng)。
          這是使用Node和Redis制作自己的速率限制器的一種方法:
          1. 創(chuàng)建一個(gè)Node應(yīng)用

          2. 使用Redis添加速率限制器

          3. 在Postman中測(cè)試

          在GitHub上查看代碼示例。
          在開(kāi)始之前,請(qǐng)確保已在計(jì)算機(jī)上安裝了Node和Redis。

          步驟1:建立Node應(yīng)用程序

          從命令行設(shè)置一個(gè)新的Node應(yīng)用。通過(guò)CLI提示,或添加?—yes 標(biāo)志來(lái)接受默認(rèn)選項(xiàng)。
          $ npm init --yes
          如果在項(xiàng)目設(shè)置過(guò)程中接受了默認(rèn)選項(xiàng),則為入口點(diǎn)創(chuàng)建一個(gè)名為 index.js 的文件。
          $ touch index.js
          安裝Express Web框架,然后在?index.js?中初始化服務(wù)器。
          const express = require('express')const app = express()const port = process.env.PORT || 3000
          app.get('/', (req, res) => res.send('Hello World!'))app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`))
          從命令行啟動(dòng)服務(wù)器。
          $ node index.js
          回到 index.js 中,創(chuàng)建一個(gè)路由,先檢查速率限制,如果用戶(hù)沒(méi)有超過(guò)限制再允許訪問(wèn)資源。
          app.post('/', async (req, res) => { async function isOverLimit(ip) { // to define } // 檢查率限制 let overLimit = await isOverLimit(req.ip) if (overLimit) { res.status(429).send('Too many requests - try again later') return } // 允許訪問(wèn)資源 res.send("Accessed the precious resources!")})
          在下一步中,我們將定義速率限制器函數(shù) isOverLimit。

          步驟2:使用Redis添加速率限制器

          Redis是一個(gè)內(nèi)存中鍵值數(shù)據(jù)庫(kù),因此它可以非常快速地檢索數(shù)據(jù)。使用Redis實(shí)施速率限制也非常簡(jiǎn)單。
          • 存儲(chǔ)一個(gè)像用戶(hù)IP地址一樣的key。

          • 增加從該IP發(fā)出的調(diào)用數(shù)量

          • 在指定時(shí)間段后使記錄過(guò)期

          下圖所示的限速算法是一個(gè)滑動(dòng)窗口計(jì)數(shù)器的例子。一個(gè)用戶(hù)如果提交的調(diào)用數(shù)量適中,或者隨著時(shí)間的推移將它們分隔開(kāi),就永遠(yuǎn)不會(huì)達(dá)到速率限制。超過(guò)10秒窗口內(nèi)最大請(qǐng)求的用戶(hù)必須等待足夠的時(shí)間來(lái)恢復(fù)其請(qǐng)求。
          從命令行為Node安裝一個(gè)名為ioredis的Redis客戶(hù)端。
          $ npm install ioredis
          在本地啟動(dòng)Redis服務(wù)器。
          $ redis-server
          然后在 index.js 中要求并初始化Redis客戶(hù)端。
          const redis = require('ioredis')const client = redis.createClient({ port: process.env.REDIS_PORT || 6379, host: process.env.REDIS_HOST || 'localhost',})client.on('connect', function () { console.log('connected');});
          定義我們上一步開(kāi)始寫(xiě)的isOverLimit函數(shù),按照Redis的這個(gè)模式,按照IP來(lái)保存一個(gè)計(jì)數(shù)器。
          async function isOverLimit(ip) { let res try { res = await client.incr(ip) } catch (err) { console.error('isOverLimit: could not increment key') throw err } console.log(`${ip} has value: ${res}`) if (res > 10) { return true } client.expire(ip, 10)}
          這就是速率限制器。
          當(dāng)用戶(hù)調(diào)用API時(shí),我們會(huì)檢查Redis以查看該用戶(hù)是否超出限制。如果是這樣,API將立即返回HTTP 429狀態(tài)代碼,并顯示消息 Too many requests — try again later 。如果用戶(hù)在限制之內(nèi),我們將繼續(xù)執(zhí)行下一個(gè)代碼塊,在該代碼塊中,我們可以允許訪問(wèn)受保護(hù)的資源(例如數(shù)據(jù)庫(kù))。
          在進(jìn)行速率限制檢查期間,我們?cè)赗edis中找到用戶(hù)的記錄,并增加其請(qǐng)求計(jì)數(shù),如果Redis中沒(méi)有該用戶(hù)的記錄,那么我們將創(chuàng)建一個(gè)新記錄。最后,每條記錄將在最近一次活動(dòng)的10秒內(nèi)過(guò)期。
          在下一步中,請(qǐng)確保我們的限速器正常運(yùn)行。

          步驟3:在Postman中進(jìn)行測(cè)試

          保存更改,然后重新啟動(dòng)服務(wù)器。我們將使用Postman將 POST 請(qǐng)求發(fā)送到我們的API服務(wù)器,該服務(wù)器在本地運(yùn)行,網(wǎng)址為 http:// localhost:3000。
          繼續(xù)快速連續(xù)發(fā)送請(qǐng)求以達(dá)到你的速率限制。

          關(guān)于限速的最終想法

          這是Node和Redis的速率限制器的簡(jiǎn)單示例,這只是開(kāi)始。有一堆策略和工具可以用來(lái)架構(gòu)和實(shí)現(xiàn)你的速率限制。而且還有其他的增強(qiáng)功能可以通過(guò)這個(gè)例子來(lái)探索,比如:
          • 在響應(yīng)正文或作為?Retry-after?標(biāo)頭中,讓用戶(hù)知道在重試之前應(yīng)該等待多少時(shí)間

          • 記錄達(dá)到速率限制的請(qǐng)求,以了解用戶(hù)行為并警告惡意攻擊

          • 嘗試使用其他速率限制算法或其他中間件

          請(qǐng)記住,當(dāng)你研究API限制時(shí),你是在性能、安全性和用戶(hù)體驗(yàn)之間進(jìn)行權(quán)衡。你理想的速率限制解決方案將隨著時(shí)間的推移而改變,同時(shí)也會(huì)考慮到這些因素。
          ??愛(ài)心三連擊

          1.看到這里了就點(diǎn)個(gè)在看支持下吧,你的點(diǎn)贊在看是我創(chuàng)作的動(dòng)力。

          2.關(guān)注公眾號(hào)程序員成長(zhǎng)指北,回復(fù)「1」加入高級(jí)前端交流群!「在這里有好多 前端?開(kāi)發(fā)者,會(huì)討論?前端 Node 知識(shí),互相學(xué)習(xí)」!

          3.也可添加微信【ikoala520】,一起成長(zhǎng)。

          “在看轉(zhuǎn)發(fā)”是最大的支持

          瀏覽 64
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产熟女乱伦视频 | 蜜桃视频高清无码 | 鸡巴视频久久 | 欧美一级的视频勉费看 | 青青草免费在线公开视频播放 |