透過Node+Redi實現API速率限制
速率限制可以保護和提高基於API的服務的可用性。如果你正在與一個API對話,並收到HTTP 429 Too Many Requests的回應狀態碼,表示你已經被速率限制了。這意味著你超出了在給定時間內允許的請求數量。你需要做的就是放慢腳步,稍等片刻,然後再試一次。
影片教學推薦:nodejs 教學
為什麼要速率限制?
當你考慮限制自己的基於API的服務時,你需要在使用者體驗、安全性和效能之間進行權衡。
控制資料流的最常見原因是保持基於API的服務的可用性。但也有安全方面的好處,一次無意或有意的入站流量激增,就會佔用寶貴的資源,影響其他使用者的可用性。
透過控制傳入請求的速率,你可以:
- 保障服務和資源不被「淹沒」。
- 緩和暴力攻擊
- 防止分散式阻斷服務(DDOS)攻擊
如何實施限速?
速率限制可以在客戶端級別,應用程式級別,基礎架構級別或介於兩者之間的任何位置實現。有幾種方法可以控制API服務的入站流量:
- 按使用者:追蹤使用者使用API金鑰、存取權杖或IP位址進行的呼叫
- 按地理區域劃分:例如降低每個地理區域在一天的高峰時段的速率限制
- 按伺服器:如果你有多個伺服器處理對API的不同調用,你可能會對訪問更昂貴的資源實施更嚴格的速率限制。
你可以使用這些速率限制中的任何一種(甚至組合使用)。
無論你選擇如何實現,速率限制的目標都是建立一個檢查點,該檢查點拒絕或透過存取你的資源的請求。許多程式語言和框架都有實現這一點的內建功能或中間件,還有各種速率限制演算法的選項。
這是使用Node和Redis製作自己的速率限制器的一種方法:
#建立一個Node應用程式
使用Redis新增速率限制器
在Postman中測試
在GitHub上檢視程式碼範例。
在開始之前,請確保已在電腦上安裝了Node和Redis。
步驟1:建立Node應用程式
從命令列設定一個新的Node應用。透過CLI提示,或新增 —yes
標誌來接受預設選項。
$ npm init --yes
如果在專案設定過程中接受了預設選項,則為入口點建立一個名為 index.js
的檔案。
$ touch index.js
安裝Express Web框架,然後在 index.js
中初始化伺服器。
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}`))
從命令列啟動伺服器。
$ node index.js
回到 index.js
中,建立一個路由,先檢查速率限制,如果使用者沒有超過限制再允許存取資源。
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 } // 允许访问资源 res.send("Accessed the precious resources!") })
在下一個步驟中,我們將定義速率限制器函數 isOverLimit
。
步驟2:使用Redis新增速率限制器
Redis是一個記憶體中鍵值資料庫,因此它可以非常快速地檢索資料。使用Redis實作速率限制也非常簡單。
- 儲存一個像使用者IP位址一樣的key。
- 增加從該IP發出的呼叫數量
- 在指定時間段後使記錄過期
下圖所示的限速演算法是一個滑動視窗計數器的範例。一個使用者如果提交的呼叫數量適中,或隨著時間的推移將它們分開,就永遠不會達到速率限制。超過10秒視窗內最大請求的使用者必須等待足夠的時間來恢復其請求。
從指令行為Node安裝一個名為ioredis的Redis客戶端。
$ npm install ioredis
在本機啟動Redis伺服器。
$ redis-server
然後在 index.js
中要求並初始化Redis客戶端。
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'); });
定義我們上一步開始寫的isOverLimit函數,依照Redis的這個模式,依照IP來保存一個計數器。
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) }
這就是速率限制器。
當使用者呼叫API時,我們會檢查Redis以查看該使用者是否超出限制。如果是這樣,API將立即傳回HTTP 429狀態代碼,並顯示訊息 Too many requests — try again later
。如果使用者在限制之內,我們將繼續執行下一個程式碼區塊,在該程式碼區塊中,我們可以允許存取受保護的資源(例如資料庫)。
在進行速率限制檢查期間,我們在Redis中找到使用者的記錄,並增加其請求計數,如果Redis中沒有該使用者的記錄,那麼我們將建立一個新記錄。最後,每筆記錄將在最近一次活動的10秒內過期。
在下一步中,請確保我們的限速器正常運作。
步驟3:在Postman中進行測試
儲存更改,然後重新啟動伺服器。我們將使用Postman將 POST
請求發送到我們的API伺服器,該伺服器在本地運行,網址為 http:// localhost:3000
。
繼續快速連續發送請求以達到你的速率限制。
關於限速的最終想法
這是Node和Redis的速率限制器的簡單範例,這只是開始。有一堆策略和工具可以用來架構和實現你的速率限制。而且還有其他的增強功能可以透過這個例子來探索,例如:
- 在回應正文或作為
Retry-after
標頭中,讓使用者知道在重試之前應該等待多少時間 - 記錄達到速率限制的請求,以了解使用者行為並警告惡意攻擊
- #嘗試使用其他速率限制演算法或其他中間件
請記住,當你研究API限制時,你是在效能、安全性和使用者體驗之間進行權衡。你理想的速率限制解決方案將隨著時間的推移而改變,同時也考慮到這些因素。
英文原文網址:https://codeburst.io/api-rate-limiting-with-node-and-redis-95354259c768
#更多程式相關知識,請造訪:程式設計入門! !
以上是透過Node+Redi實現API速率限制的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

nvm刪除node的方法:1、下載「nvm-setup.zip」並將其安裝在C碟;2、設定環境變量,並透過「nvm -v」指令查看版本號;3、使用「nvm install」指令安裝node;4、透過「nvm uninstall」指令刪除已安裝的node即可。

怎麼處理文件上傳?以下這篇文章為大家介紹一下node專案中如何使用express來處理文件的上傳,希望對大家有幫助!

這段時間在開發一個騰訊文檔全品類通用的HTML 動態服務,為了方便各品類接入的生成與部署,也順應上雲的趨勢,考慮使用Docker 的方式來固定服務內容,統一進行製品版本的管理。這篇文章就將我在服務 Docker 化的過程中累積起來的優化經驗分享出來,供大家參考。

這篇文章跟大家分享Node的進程管理工具“pm2”,聊聊為什麼需要pm2、安裝和使用pm2的方法,希望對大家有幫助!

PiNetwork節點詳解及安裝指南本文將詳細介紹PiNetwork生態系統中的關鍵角色——Pi節點,並提供安裝和配置的完整步驟。 Pi節點在PiNetwork區塊鏈測試網推出後,成為眾多先鋒積極參與測試的重要環節,為即將到來的主網發布做準備。如果您還不了解PiNetwork,請參考Pi幣是什麼?上市價格多少? Pi用途、挖礦及安全性分析。什麼是PiNetwork? PiNetwork項目始於2019年,擁有其專屬加密貨幣Pi幣。該項目旨在創建一個人人可參與

如何用pkg打包nodejs可執行檔?以下這篇文章跟大家介紹一下使用pkg將Node專案打包為執行檔的方法,希望對大家有幫助!

npm node gyp失敗是因為“node-gyp.js”跟“Node.js”版本不匹配,其解決辦法:1、透過“npm cache clean -f”清除node快取;2、透過“npm install -g n”安裝n模組;3、透過「n v12.21.0」指令安裝「node v12.21.0」版本即可。

身份驗證是任何網路應用程式中最重要的部分之一。本教程討論基於令牌的身份驗證系統以及它們與傳統登入系統的差異。在本教程結束時,您將看到一個用Angular和Node.js編寫的完整工作演示。傳統身份驗證系統在繼續基於令牌的身份驗證系統之前,讓我們先來看看傳統的身份驗證系統。使用者在登入表單中提供使用者名稱和密碼,然後點擊登入。發出請求後,透過查詢資料庫在後端驗證使用者。如果請求有效,則使用從資料庫中獲取的使用者資訊建立會話,然後在回應頭中傳回會話訊息,以便將會話ID儲存在瀏覽器中。提供用於存取應用程式中受
