保護(hù)高并發(fā)服務(wù)穩(wěn)定主要有三把利器:緩存、降級和限流
前言
在當(dāng)今數(shù)字化時(shí)代,互聯(lián)網(wǎng)應(yīng)用面臨著前所未有的高并發(fā)挑戰(zhàn)。無論是電商平臺的促銷活動(dòng)、社交媒體的熱點(diǎn)事件,還是在線游戲的高峰時(shí)段,大量用戶的同時(shí)訪問對服務(wù)的穩(wěn)定性構(gòu)成了巨大威脅。
隨著微服務(wù)的流行,服務(wù)之間的依賴性和調(diào)用關(guān)系變得越來越復(fù)雜,服務(wù)的穩(wěn)定性變得尤為重要。業(yè)務(wù)場景中經(jīng)常會涉及到瞬時(shí)流量沖擊,可能會導(dǎo)致請求響應(yīng)超時(shí),甚至服務(wù)器被壓垮、宕機(jī)不可用。
出于對系統(tǒng)本身和上下游服務(wù)的保護(hù),我們引入了緩存、降級和限流。
緩存
緩存是一種用于存儲經(jīng)常訪問的數(shù)據(jù)副本的技術(shù),其主要目的是減少對原始數(shù)據(jù)源(如數(shù)據(jù)庫)的訪問,從而顯著提升系統(tǒng)的響應(yīng)速度和吞吐量。在高并發(fā)環(huán)境下,緩存的作用尤為突出,它可以有效減輕后端數(shù)據(jù)源的負(fù)載壓力,防止其因大量請求而不堪重負(fù)。
工作原理
緩存的工作原理基于一個(gè)簡單而高效的機(jī)制:當(dāng)應(yīng)用程序請求數(shù)據(jù)時(shí),它首先會檢查緩存中是否已經(jīng)存在該數(shù)據(jù)。如果緩存命中,即數(shù)據(jù)已存在于緩存中,應(yīng)用程序可以直接從緩存中獲取數(shù)據(jù)并返回給用戶,這一過程幾乎是瞬間完成的。反之,如果緩存未命中,應(yīng)用程序則需要從原始數(shù)據(jù)源(如數(shù)據(jù)庫)中讀取數(shù)據(jù),然后將數(shù)據(jù)存儲到緩存中,以便后續(xù)請求能夠更快地獲取。
緩存的應(yīng)用層次
緩存可以應(yīng)用在多個(gè)層次,每個(gè)層次都有其獨(dú)特的優(yōu)勢和適用場景:
- 瀏覽器緩存:瀏覽器緩存是最接近用戶的緩存層次,它允許瀏覽器在本地存儲網(wǎng)頁資源(如
HTML、CSS、JavaScript文件以及圖片等)。當(dāng)用戶再次訪問相同的網(wǎng)頁時(shí),瀏覽器可以直接從本地緩存中加載這些資源,而無需再次向服務(wù)器發(fā)送請求。這不僅大大加快了網(wǎng)頁的加載速度,還減少了網(wǎng)絡(luò)流量和服務(wù)器的負(fù)載。 CDN緩存:內(nèi)容分發(fā)網(wǎng)絡(luò)(CDN)緩存通過在全球各地部署節(jié)點(diǎn)服務(wù)器,將靜態(tài)內(nèi)容(如圖片、視頻、腳本文件等)緩存到離用戶最近的節(jié)點(diǎn)上。當(dāng)用戶請求這些內(nèi)容時(shí),CDN服務(wù)器可以直接從本地緩存中提供數(shù)據(jù),而無需將請求轉(zhuǎn)發(fā)回源服務(wù)器。CDN緩存能夠顯著降低用戶的訪問延遲,提高網(wǎng)站的性能和可用性,尤其對于全球范圍內(nèi)的用戶訪問效果更為明顯。- 反向代理緩存:反向代理服務(wù)器位于應(yīng)用服務(wù)器之前,它可以緩存應(yīng)用服務(wù)器的響應(yīng)結(jié)果。當(dāng)有新的請求到達(dá)時(shí),反向代理首先檢查緩存中是否存在匹配的響應(yīng),如果存在,則直接返回給客戶端,而無需將請求轉(zhuǎn)發(fā)給應(yīng)用服務(wù)器。反向代理緩存可以有效減輕應(yīng)用服務(wù)器的負(fù)載,提高系統(tǒng)的整體性能。常見的反向代理服務(wù)器軟件如
Nginx、Apache等都支持緩存功能。 - 應(yīng)用緩存:應(yīng)用緩存是在應(yīng)用程序內(nèi)部實(shí)現(xiàn)的緩存機(jī)制,它通常用于緩存應(yīng)用程序頻繁訪問的數(shù)據(jù)或計(jì)算結(jié)果。應(yīng)用緩存可以根據(jù)應(yīng)用的需求進(jìn)行定制化開發(fā),靈活性較高。例如,在
Java應(yīng)用中,可以使用Ehcache、Caffeine等緩存框架來實(shí)現(xiàn)應(yīng)用緩存功能。
緩存的挑戰(zhàn)與解決方案
雖然緩存能夠帶來顯著的性能提升,但在實(shí)際應(yīng)用中也面臨一些挑戰(zhàn):
- 緩存穿透:緩存穿透是指查詢一個(gè)在緩存和數(shù)據(jù)庫中都不存在的數(shù)據(jù),導(dǎo)致每次請求都繞過緩存直接查詢數(shù)據(jù)庫。這種情況可能是由于惡意攻擊或者業(yè)務(wù)邏輯錯(cuò)誤導(dǎo)致的。為了解決緩存穿透問題,可以采用以下幾種方法:
參數(shù)校驗(yàn):在應(yīng)用程序入口處對請求參數(shù)進(jìn)行嚴(yán)格校驗(yàn),確保參數(shù)的合法性,例如檢查查詢 ID 是否為負(fù)數(shù)或超出合理范圍等。
布隆過濾器:布隆過濾器是一種高效的數(shù)據(jù)結(jié)構(gòu),它可以用于判斷一個(gè)元素是否存在于一個(gè)集合中。通過在緩存之前使用布隆過濾器,可以快速過濾掉不存在的數(shù)據(jù)請求,避免這些請求直接訪問數(shù)據(jù)庫。
緩存空值:當(dāng)查詢數(shù)據(jù)庫未找到數(shù)據(jù)時(shí),可以將空值緩存起來,并設(shè)置一個(gè)較短的過期時(shí)間,這樣在過期時(shí)間內(nèi)相同的請求將直接從緩存中獲取空值,而不會再次查詢數(shù)據(jù)庫。
- 緩存擊穿:緩存擊穿是指在緩存過期的瞬間,大量并發(fā)請求同時(shí)訪問該緩存對應(yīng)的數(shù)據(jù)庫數(shù)據(jù),導(dǎo)致數(shù)據(jù)庫壓力瞬間增大。為了解決緩存擊穿問題,可以考慮以下方法:
- 熱點(diǎn)數(shù)據(jù)永不過期:對于一些熱點(diǎn)數(shù)據(jù),可以設(shè)置其在緩存中永不過期,或者將過期時(shí)間設(shè)置得足夠長,以避免因緩存過期而導(dǎo)致的并發(fā)訪問問題。
- 加鎖機(jī)制:在從數(shù)據(jù)庫讀取數(shù)據(jù)并更新緩存時(shí),可以使用分布式鎖或本地鎖來保證同一時(shí)間只有一個(gè)線程能夠訪問數(shù)據(jù)庫,其他線程等待鎖釋放后從緩存中獲取數(shù)據(jù)。這樣可以避免大量并發(fā)請求同時(shí)查詢數(shù)據(jù)庫。
- 緩存雪崩:緩存雪崩是指在某一時(shí)刻,大量緩存同時(shí)過期,導(dǎo)致大量請求同時(shí)涌向數(shù)據(jù)庫,造成數(shù)據(jù)庫壓力過大甚至崩潰。為了防止緩存雪崩,可以采取以下措施:
- 隨機(jī)過期時(shí)間:在設(shè)置緩存過期時(shí)間時(shí),為每個(gè)緩存項(xiàng)設(shè)置一個(gè)隨機(jī)的過期時(shí)間,避免大量緩存同時(shí)過期。
- 多級緩存:采用多級緩存架構(gòu),例如同時(shí)使用內(nèi)存緩存和磁盤緩存。當(dāng)內(nèi)存緩存失效時(shí),可以從磁盤緩存中獲取數(shù)據(jù),從而減輕數(shù)據(jù)庫的壓力。
- 緩存預(yù)熱:在系統(tǒng)啟動(dòng)時(shí),提前將一些熱點(diǎn)數(shù)據(jù)加載到緩存中,避免在系統(tǒng)運(yùn)行初期因緩存未命中而導(dǎo)致大量請求直接訪問數(shù)據(jù)庫。
降級
降級是在系統(tǒng)面臨高壓力或出現(xiàn)故障時(shí)采取的一種應(yīng)急策略,其核心思想是在資源有限的情況下,通過犧牲部分非核心業(yè)務(wù)的功能來保證核心業(yè)務(wù)的正常運(yùn)行。降級策略可以幫助系統(tǒng)在極端情況下保持基本的可用性,避免因系統(tǒng)崩潰而導(dǎo)致的全面服務(wù)中斷。
降級的觸發(fā)條件
降級通常在以下幾種情況下觸發(fā):
- 系統(tǒng)負(fù)載過高:當(dāng)系統(tǒng)的
CPU、內(nèi)存、磁盤I/O或網(wǎng)絡(luò)帶寬等資源利用率達(dá)到或超過設(shè)定的閾值時(shí),表明系統(tǒng)負(fù)載過高,可能無法同時(shí)處理所有請求。此時(shí),可以觸發(fā)降級策略,減少對資源消耗較大的非核心業(yè)務(wù)的處理,以保證核心業(yè)務(wù)有足夠的資源運(yùn)行。 - 服務(wù)故障:當(dāng)某個(gè)關(guān)鍵服務(wù)出現(xiàn)故障或不可用時(shí),為了防止故障蔓延影響整個(gè)系統(tǒng),可能需要對依賴該服務(wù)的其他業(yè)務(wù)進(jìn)行降級處理。例如,如果第三方支付接口出現(xiàn)故障,電商平臺可以暫時(shí)關(guān)閉在線支付功能,引導(dǎo)用戶選擇其他支付方式,同時(shí)保證商品瀏覽、下單等核心功能的正常運(yùn)行。
- 網(wǎng)絡(luò)故障:在網(wǎng)絡(luò)不穩(wěn)定或出現(xiàn)大面積網(wǎng)絡(luò)故障時(shí),為了避免因網(wǎng)絡(luò)延遲或超時(shí)導(dǎo)致用戶體驗(yàn)惡化,可以對一些對網(wǎng)絡(luò)要求較高的非核心業(yè)務(wù)進(jìn)行降級。比如,暫停實(shí)時(shí)數(shù)據(jù)同步功能,改為異步批量同步,以減少網(wǎng)絡(luò)請求的頻率和壓力。
降級的實(shí)現(xiàn)方式
降級可以在多個(gè)層次進(jìn)行,常見的降級方式包括:
- 頁面降級:頁面降級是指在系統(tǒng)壓力較大時(shí),將一些復(fù)雜的頁面簡化為靜態(tài)頁面或只展示核心信息。例如,在電商大促期間,為了減輕服務(wù)器壓力,可以將商品詳情頁中的一些動(dòng)態(tài)元素(如實(shí)時(shí)推薦、用戶評價(jià)滾動(dòng)條等)去掉,只保留商品基本信息、圖片和價(jià)格等核心內(nèi)容。這樣可以減少頁面渲染所需的資源和時(shí)間,提高頁面加載速度。
- 功能降級:功能降級是指關(guān)閉或限制一些非核心功能的使用。例如,在社交媒體平臺流量高峰時(shí),可以暫時(shí)關(guān)閉圖片上傳、視頻播放等占用大量帶寬和資源的功能,只保留文字發(fā)布、點(diǎn)贊、評論等基本功能。這樣可以在保證用戶基本社交需求的同時(shí),降低系統(tǒng)的負(fù)載壓力。
- 服務(wù)降級:服務(wù)降級是指對一些非核心服務(wù)進(jìn)行降級處理,例如降低服務(wù)的響應(yīng)質(zhì)量或頻率。比如,在訂單處理系統(tǒng)中,當(dāng)訂單量過大時(shí),可以將訂單的實(shí)時(shí)處理改為異步處理,將一些非關(guān)鍵的訂單校驗(yàn)邏輯簡化或延遲執(zhí)行,以提高訂單處理的吞吐量。同時(shí),可以返回給用戶一個(gè)友好的提示信息,告知用戶訂單已提交成功,正在處理中,讓用戶了解訂單的狀態(tài)。
降級策略的制定與管理
制定降級策略需要綜合考慮業(yè)務(wù)的重要性、用戶體驗(yàn)以及系統(tǒng)資源的實(shí)際情況。在制定降級策略時(shí),需要注意以下幾點(diǎn):
- 明確核心業(yè)務(wù)與非核心業(yè)務(wù):首先要對業(yè)務(wù)進(jìn)行梳理和分類,明確哪些是核心業(yè)務(wù),哪些是非核心業(yè)務(wù)。核心業(yè)務(wù)是指對用戶體驗(yàn)和業(yè)務(wù)運(yùn)營至關(guān)重要的功能,如電商平臺的下單支付功能、社交媒體平臺的用戶登錄和信息發(fā)布功能等。非核心業(yè)務(wù)則是指那些對用戶體驗(yàn)影響較小、可以在緊急情況下暫時(shí)犧牲的功能。
- 合理設(shè)置降級閾值:根據(jù)系統(tǒng)的性能指標(biāo)和歷史數(shù)據(jù),合理設(shè)置降級的觸發(fā)閾值。閾值設(shè)置過低可能導(dǎo)致頻繁降級,影響用戶體驗(yàn);閾值設(shè)置過高則可能無法及時(shí)有效地保護(hù)系統(tǒng)。例如,可以根據(jù)系統(tǒng)的
CPU使用率、內(nèi)存使用率、并發(fā)請求數(shù)等指標(biāo)來設(shè)置降級閾值。 - 提供友好的用戶提示:在進(jìn)行降級處理時(shí),要及時(shí)向用戶提供友好的提示信息,告知用戶當(dāng)前系統(tǒng)的狀態(tài)以及相關(guān)功能的調(diào)整情況。這樣可以避免用戶因功能異常而產(chǎn)生困惑和不滿,提高用戶的滿意度和信任度。例如,可以在頁面上顯示一個(gè)全局提示框,說明由于系統(tǒng)繁忙,部分功能已暫時(shí)調(diào)整,給用戶帶來的不便敬請諒解。
- 實(shí)時(shí)監(jiān)控與動(dòng)態(tài)調(diào)整:建立實(shí)時(shí)監(jiān)控系統(tǒng),對系統(tǒng)的運(yùn)行狀態(tài)、業(yè)務(wù)指標(biāo)以及降級策略的執(zhí)行情況進(jìn)行實(shí)時(shí)監(jiān)控。根據(jù)監(jiān)控?cái)?shù)據(jù),及時(shí)發(fā)現(xiàn)問題并對降級策略進(jìn)行動(dòng)態(tài)調(diào)整。例如,如果發(fā)現(xiàn)某個(gè)非核心業(yè)務(wù)在降級后對用戶體驗(yàn)影響較大,可以適當(dāng)放寬該業(yè)務(wù)的降級條件;如果發(fā)現(xiàn)系統(tǒng)負(fù)載壓力進(jìn)一步增大,可以進(jìn)一步加強(qiáng)降級措施。
限流
流是一種通過限制系統(tǒng)處理請求的速率或數(shù)量來保護(hù)系統(tǒng)免受過載的技術(shù)。在高并發(fā)場景下,限流可以防止系統(tǒng)因瞬間涌入的大量請求而導(dǎo)致資源耗盡、響應(yīng)變慢甚至崩潰。限流就像一個(gè)閥門,能夠有效地控制進(jìn)入系統(tǒng)的流量,確保系統(tǒng)在其處理能力范圍內(nèi)穩(wěn)定運(yùn)行。
限流的目的與作用
限流的主要目的和作用包括以下幾個(gè)方面:
- 保護(hù)系統(tǒng)資源:系統(tǒng)的資源(如
CPU、內(nèi)存、網(wǎng)絡(luò)帶寬、數(shù)據(jù)庫連接等)是有限的,當(dāng)大量請求同時(shí)到達(dá)時(shí),可能會導(dǎo)致資源耗盡。通過限流,可以將請求速率控制在系統(tǒng)能夠承受的范圍內(nèi),避免因資源過度消耗而導(dǎo)致系統(tǒng)故障。 - 保證服務(wù)質(zhì)量:當(dāng)系統(tǒng)負(fù)載過高時(shí),響應(yīng)時(shí)間會顯著增加,甚至出現(xiàn)超時(shí)現(xiàn)象,這將嚴(yán)重影響用戶體驗(yàn)。限流可以確保系統(tǒng)在高并發(fā)情況下仍能保持一定的響應(yīng)速度和服務(wù)質(zhì)量,為用戶提供穩(wěn)定可靠的服務(wù)。
- 防止惡意攻擊:某些惡意攻擊者可能會通過發(fā)送大量請求來對系統(tǒng)進(jìn)行
DDoS(分布式拒絕服務(wù))攻擊,試圖使系統(tǒng)癱瘓。限流可以有效地抵御這類攻擊,通過限制單個(gè)IP或用戶的請求速率,防止惡意請求對系統(tǒng)造成損害。
限流的常見算法
實(shí)現(xiàn)限流的關(guān)鍵在于選擇合適的算法,常見的限流算法有以下幾種:
圖片
令牌桶算法:令牌桶算法是一種廣泛應(yīng)用的限流算法。其核心思想是系統(tǒng)以固定的速率生成令牌,并將令牌放入一個(gè)桶中。當(dāng)請求到達(dá)時(shí),嘗試從桶中獲取令牌,如果桶中有足夠的令牌,則請求被允許通過;否則,請求將被拒絕或等待。令牌桶算法的特點(diǎn)是允許一定程度的突發(fā)流量,因?yàn)橥翱梢源鎯σ欢〝?shù)量的令牌,當(dāng)有突發(fā)請求時(shí),可以消耗桶中積累的令牌。例如,假設(shè)系統(tǒng)以每秒 10 個(gè)令牌的速率生成令牌,令牌桶的容量為 100 個(gè)。如果在某一時(shí)刻,桶中有 50 個(gè)令牌,此時(shí)突然來了 80 個(gè)請求,由于桶中有足夠的令牌(50 個(gè)),這 80 個(gè)請求中的 50 個(gè)可以立即通過,剩余 30 個(gè)請求則需要等待新的令牌生成或者被拒絕。
圖片
漏桶算法:漏桶算法與令牌桶算法類似,但工作方式略有不同。漏桶算法將請求看作水流,請求進(jìn)入一個(gè)固定容量的桶中,桶以固定的速率將請求流出(即處理請求)。如果桶已滿,新的請求將被丟棄。漏桶算法的優(yōu)點(diǎn)是能夠平滑地處理請求,確保請求以穩(wěn)定的速率被處理,不會出現(xiàn)突發(fā)流量。但其缺點(diǎn)是對突發(fā)流量的處理能力較弱,當(dāng)突發(fā)大量請求時(shí),可能會導(dǎo)致部分請求被丟棄。例如,假設(shè)漏桶的容量為 100,流出速率為每秒 10 個(gè)請求。如果在某一時(shí)刻,突然來了 150 個(gè)請求,由于桶的容量限制,只能容納 100 個(gè)請求,剩余 50 個(gè)請求將被丟棄,而桶中的請求將以每秒 10 個(gè)的速率被逐步處理。
圖片
固定窗口計(jì)數(shù)器算法:固定窗口計(jì)數(shù)器算法是一種簡單直觀的限流算法。它將時(shí)間劃分為固定的窗口,例如每秒、每分鐘等,并在每個(gè)窗口內(nèi)統(tǒng)計(jì)請求的數(shù)量。當(dāng)請求到達(dá)時(shí),檢查當(dāng)前窗口內(nèi)的請求數(shù)量是否超過了設(shè)定的閾值,如果超過,則拒絕該請求;否則,允許請求通過并將計(jì)數(shù)器加 1。固定窗口計(jì)數(shù)器算法的實(shí)現(xiàn)簡單,但存在明顯的臨界問題。例如,假設(shè)限流閾值為每分鐘 100 個(gè)請求,窗口時(shí)間為 1 分鐘。如果在第 1 分鐘的最后幾秒和第 2 分鐘的最初幾秒內(nèi),分別有 90 個(gè)請求到達(dá),雖然在每個(gè)單獨(dú)的 1 分鐘窗口內(nèi)請求數(shù)量都未超過閾值,但在這兩個(gè)窗口的重疊時(shí)間段內(nèi),請求總數(shù)達(dá)到了 180 個(gè),已經(jīng)超過了限流閾值,可能導(dǎo)致系統(tǒng)過載。
圖片
滑動(dòng)窗口計(jì)數(shù)器算法:滑動(dòng)窗口計(jì)數(shù)器算法是對固定窗口計(jì)數(shù)器算法的改進(jìn),它通過將大的時(shí)間窗口劃分為多個(gè)小的子窗口,每個(gè)子窗口獨(dú)立統(tǒng)計(jì)請求數(shù)量,并隨著時(shí)間的推移滑動(dòng)窗口,從而更精確地控制請求速率?;瑒?dòng)窗口計(jì)數(shù)器算法能夠有效解決固定窗口計(jì)數(shù)器算法的臨界問題,提高限流的準(zhǔn)確性。例如,將 1 分鐘的時(shí)間窗口劃分為 60 個(gè) 1 秒的子窗口,每個(gè)子窗口內(nèi)統(tǒng)計(jì)請求數(shù)量。當(dāng)時(shí)間從第 1 秒滑動(dòng)到第 2 秒時(shí),第 1 秒的子窗口統(tǒng)計(jì)數(shù)據(jù)被移除,同時(shí)加入第 61 秒的子窗口統(tǒng)計(jì)數(shù)據(jù)。這樣,無論請求在時(shí)間上如何分布,都能更準(zhǔn)確地進(jìn)行限流控制。
四種基本算法的對比:
圖片
限流的應(yīng)用場景
限流在各種高并發(fā)場景中都有廣泛的應(yīng)用,以下是一些常見的應(yīng)用場景:
- 秒殺活動(dòng):在電商平臺的秒殺活動(dòng)中,由于參與人數(shù)眾多,瞬間會產(chǎn)生大量的請求。通過限流可以控制每秒進(jìn)入秒殺系統(tǒng)的請求數(shù)量,避免系統(tǒng)因高并發(fā)請求而崩潰,同時(shí)保證每個(gè)用戶都有公平參與秒殺的機(jī)會。例如,可以根據(jù)系統(tǒng)的處理能力,設(shè)置每秒只允許 1000 個(gè)請求進(jìn)入秒殺系統(tǒng),超出部分的請求將被限流提示用戶稍后再試。
- API 接口訪問:對于一些提供對外 API 服務(wù)的平臺,為了保護(hù)自身系統(tǒng)的穩(wěn)定性和資源,需要對 API 接口的調(diào)用頻率進(jìn)行限制。例如,限制每個(gè)用戶每分鐘最多調(diào)用某個(gè) API 接口 100 次,超出次數(shù)的調(diào)用將返回錯(cuò)誤信息,提示用戶調(diào)用頻率過高。這樣可以防止個(gè)別用戶或應(yīng)用程序?yàn)E用 API 接口,對平臺造成過大的壓力。
- 登錄注冊:在用戶登錄和注冊功能中,為了防止惡意用戶通過暴力破解密碼或頻繁注冊賬號進(jìn)行攻擊,可以對單個(gè) IP 地址或用戶的登錄注冊請求頻率進(jìn)行限流。例如,限制每個(gè) IP 地址每分鐘最多進(jìn)行 5 次登錄嘗試或 10 次注冊操作,超出限制的請求將被暫時(shí)封禁一段時(shí)間,以提高系統(tǒng)的安全性。
- 視頻直播:在視頻直播場景中,為了保證直播的流暢性和穩(wěn)定性,需要對觀眾的并發(fā)訪問數(shù)量進(jìn)行限流。例如,根據(jù)服務(wù)器的帶寬和處理能力,限制每個(gè)直播間同時(shí)在線觀看的人數(shù)不超過 10000 人,當(dāng)人數(shù)達(dá)到上限時(shí),新的觀眾將無法進(jìn)入直播間,只能等待其他觀眾離開后才有機(jī)會進(jìn)入。
限流的實(shí)現(xiàn)方式
限流可以在不同的層次進(jìn)行實(shí)現(xiàn),常見的實(shí)現(xiàn)方式包括:
- 應(yīng)用層限流:應(yīng)用層限流是在應(yīng)用程序內(nèi)部實(shí)現(xiàn)的限流邏輯,通常可以通過編寫代碼來實(shí)現(xiàn)。例如,在 Java 應(yīng)用中,可以使用 Guava 庫中的 RateLimiter 類來實(shí)現(xiàn)令牌桶算法的限流功能。在應(yīng)用層實(shí)現(xiàn)限流的優(yōu)點(diǎn)是可以根據(jù)業(yè)務(wù)需求進(jìn)行靈活定制,能夠精確控制每個(gè)業(yè)務(wù)模塊的限流策略。但其缺點(diǎn)是如果應(yīng)用程序部署在多個(gè)服務(wù)器上,應(yīng)用層限流只能對單個(gè)服務(wù)器上的請求進(jìn)行限制,無法實(shí)現(xiàn)全局統(tǒng)一的限流。
- 網(wǎng)關(guān)層限流:網(wǎng)關(guān)作為系統(tǒng)的入口,是進(jìn)行限流的理想位置。通過在網(wǎng)關(guān)層設(shè)置限流規(guī)則,可以對所有進(jìn)入系統(tǒng)的請求進(jìn)行統(tǒng)一的流量控制。常見的網(wǎng)關(guān)軟件如 Nginx、Kong 等都提供了強(qiáng)大的限流功能。例如,Nginx 可以使用 limit_req_zone 指令來實(shí)現(xiàn)基于令牌桶算法的速率限流,使用 limit_conn_zone 指令來實(shí)現(xiàn)基于并發(fā)連接數(shù)的限流。網(wǎng)關(guān)層限流的優(yōu)點(diǎn)是可以對整個(gè)系統(tǒng)的流量進(jìn)行集中管理和控制,并且可以很方便地對不同的服務(wù)或接口設(shè)置不同的限流策略。同時(shí),由于網(wǎng)關(guān)通常具有較高的性能和并發(fā)處理能力,能夠承受大量的請求流量,因此在網(wǎng)關(guān)層進(jìn)行限流不會對系統(tǒng)的性能產(chǎn)生較大影響。
- 中間件限流:除了應(yīng)用層和網(wǎng)關(guān)層,還可以利用中間件來實(shí)現(xiàn)限流功能。例如,使用 Redis 作為分布式緩存中間件時(shí),可以結(jié)合 Lua 腳本來實(shí)現(xiàn)基于 Redis 的限流。通過在 Redis 中維護(hù)一個(gè)計(jì)數(shù)器,每次請求到達(dá)時(shí),通過 Lua 腳本原子性地增加計(jì)數(shù)器的值,并與限流閾值進(jìn)行比較,從而實(shí)現(xiàn)限流控制。中間件限流的優(yōu)點(diǎn)是可以利用中間。
總結(jié)
這三把利器各有其特點(diǎn),通常會結(jié)合使用,以達(dá)到最佳的效果。例如,可以通過緩存來減少數(shù)據(jù)庫的訪問,通過降級來應(yīng)對系統(tǒng)故障,通過限流來防止系統(tǒng)過載。在設(shè)計(jì)高并發(fā)系統(tǒng)時(shí),需要根據(jù)系統(tǒng)的具體需求和特點(diǎn),合理地使用這些技術(shù)。




























