色婷婷狠狠18禁久久YY,CHINESE性内射高清国产,国产女人18毛片水真多1,国产AV在线观看

微服務(wù)如何限制接口調(diào)用次數(shù)

微服務(wù)如何限制接口調(diào)用次數(shù)?

這種限制接口調(diào)用次數(shù)的方式,我們通常稱(chēng)之為限流,那么為什么要做限流呢,一般有兩種原因:

1. 首先是防止服務(wù)提供方被大量的請(qǐng)求擊垮

我們開(kāi)發(fā)一個(gè)項(xiàng)目,最理想的狀況是有多少請(qǐng)求,都可以正常地響應(yīng),但是在現(xiàn)在的互聯(lián)網(wǎng)環(huán)境,我們很難評(píng)估用戶(hù)的增長(zhǎng),很難評(píng)估訪(fǎng)問(wèn)量有多少,甚至有些時(shí)候會(huì)遇到惡意攻擊;那么相比于項(xiàng)目被流量擊垮,【限制流量,只滿(mǎn)足部分訪(fǎng)問(wèn)的正常響應(yīng)】要好一些。

簡(jiǎn)單說(shuō)就是:滿(mǎn)足所有請(qǐng)求 > 滿(mǎn)足部分請(qǐng)求 > 項(xiàng)目被擊垮,所有請(qǐng)求無(wú)法響應(yīng)。

2. 計(jì)費(fèi)

現(xiàn)在很多平臺(tái)對(duì)外開(kāi)發(fā)的接口,并不全是免費(fèi)的,比如普通會(huì)員每天只能調(diào)用 1000 次接口,高級(jí)會(huì)員每天可以調(diào)用 10 萬(wàn)次接口,或者按照調(diào)用量計(jì)費(fèi)。

那么如何限制服務(wù)接口的調(diào)用次數(shù)呢?

使用限流算法

通常我們可以通過(guò)限流算法達(dá)到限制接口調(diào)用次數(shù),比如計(jì)數(shù)器法、滑動(dòng)窗口法、漏桶算法、令牌桶算法,這里我們就用令牌桶算法舉例。

令牌桶算法,我們可以看做有一個(gè)桶,桶里面有 N 個(gè)令牌,并且系統(tǒng)會(huì)以一個(gè)恒定的速度往桶里投放令牌,每次處理之前先要獲取令牌,如果獲取不到的話(huà),就拒絕服務(wù);在這里我們使用 Google 出品的 Guava 工具庫(kù),里面提供了一個(gè)開(kāi)箱即用的令牌桶 RateLimiter。

如圖,我們編寫(xiě)了一個(gè)簡(jiǎn)單的接口,省略了業(yè)務(wù)邏輯,只返回一個(gè)字符串;我們?cè)O(shè)置 RateLimiter.create(2),表示每秒不超過(guò) 2 個(gè)任務(wù)被提交。

讓我們用接口工具模擬一下并發(fā)調(diào)用:

他強(qiáng)任他強(qiáng),我自巍然不動(dòng)。因?yàn)槲覀兪褂昧讼蘖魉惴ǎ棵胫惶幚?2 個(gè)請(qǐng)求,所以從日志中我們可以看到這樣的效果:每秒只有兩條日志。

分布式架構(gòu)下的限流

因?yàn)槭褂瞄_(kāi)源的組件,限流的實(shí)現(xiàn)看起來(lái)非常簡(jiǎn)單,但是這里也有一個(gè)比較大的問(wèn)題,就是實(shí)例中是一個(gè)應(yīng)用包,但在實(shí)際的項(xiàng)目中,我們通常會(huì)是用集群部署的方式,將我們的應(yīng)用部署在多臺(tái)機(jī)器上,那么這時(shí)候該如何限流呢?

每臺(tái)服務(wù)器上的應(yīng)用自己控制自己的響應(yīng)數(shù)量?比如每天只能調(diào) 100 次,那部署 10 臺(tái)的話(huà),總量就變成了 1000 次了;

反推?因?yàn)槊刻炜偭恐荒苷{(diào) 100 次,部署 10 臺(tái),那就是每臺(tái)每天只能調(diào) 10 次?這是個(gè)很差的辦法,先不說(shuō)流量一定可以平均分配到每臺(tái)機(jī)器上,如果有一臺(tái)機(jī)器掛掉了,是不是今天只能支持調(diào)用 90 次了?

通常的解決方案,可以把令牌桶中的令牌,不要放在本地,而是放在一個(gè)公共的地方,比如 Redis 中,每次請(qǐng)求過(guò)來(lái),就計(jì)算是否超過(guò)限制的總量,如果未超過(guò),則正常處理,如果已超過(guò),則返回錯(cuò)誤信息。

具體做法是,用 Redis 中的 key-100 作為令牌桶,其中 100 表示一分鐘可以調(diào)用 100 次,每次處理前對(duì) value 進(jìn)行減 1,返回的值大于 0 表示可以處理;每分鐘將 value 設(shè)置回 100;或計(jì)數(shù)累加,開(kāi)始是 0 ,不斷累加,最后超過(guò)單位時(shí)間的總量限制;

不過(guò)這個(gè)方法要有一個(gè)定時(shí)任務(wù),去設(shè)置令牌的數(shù)量,另外這種方法是不能應(yīng)對(duì)突發(fā)流量的,比如前 59 秒一次請(qǐng)求也沒(méi)有,第 60 秒來(lái)了 100 次,第 61 秒進(jìn)入了一個(gè)新的周期,又來(lái)了 100 次請(qǐng)求 ,這樣實(shí)際上是在兩秒內(nèi)處理了 200 次請(qǐng)求。

另外一種方案是使用 Redis 中的有序隊(duì)列 Sorted Set ,存儲(chǔ)近 100 次的調(diào)用時(shí)間,每次有新請(qǐng)求的時(shí)候,對(duì)比隊(duì)列中第一個(gè)元素的時(shí)間和當(dāng)前時(shí)間,如果相差超過(guò) 1 分鐘,表示還沒(méi)有超過(guò)流量限制,進(jìn)行處理,并將第一個(gè)元素壓出隊(duì)列,將新的請(qǐng)求時(shí)間壓入隊(duì)列。

我將持續(xù)分享Java開(kāi)發(fā)、架構(gòu)設(shè)計(jì)、程序員職業(yè)發(fā)展等方面的見(jiàn)解,希望能得到你的關(guān)注。

秒殺 java,微服務(wù)如何限制接口調(diào)用次數(shù)