成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

分布式服務(wù)限流實(shí)戰(zhàn),已經(jīng)為你排好坑了|總結(jié)的很全面-創(chuàng)新互聯(lián)

一、限流的作用

創(chuàng)新互聯(lián)專注于企業(yè)網(wǎng)絡(luò)營銷推廣、網(wǎng)站重做改版、大觀網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、html5、商城建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站制作、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為大觀等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。

由于API接口無法控制調(diào)用方的行為,因此當(dāng)遇到瞬時(shí)請求量激增時(shí),會(huì)導(dǎo)致接口占用過多服務(wù)器資源,使得其他請求響應(yīng)速度降低或是超時(shí),更有甚者可能導(dǎo)致服務(wù)器宕機(jī)。

限流(Rate limiting)指對應(yīng)用服務(wù)的請求進(jìn)行限制,例如某一接口的請求限制為100個(gè)每秒,對超過限制的請求則進(jìn)行快速失敗或丟棄。

限流可以應(yīng)對:

  • 熱點(diǎn)業(yè)務(wù)帶來的突發(fā)請求;

  • 調(diào)用方bug導(dǎo)致的突發(fā)請求;

  • 惡意gonji請求。

因此,對于公開的接口最好采取限流措施。

二、為什么要分布式限流

分布式服務(wù)限流實(shí)戰(zhàn),已經(jīng)為你排好坑了 | 總結(jié)的很全面

當(dāng)應(yīng)用為單點(diǎn)應(yīng)用時(shí),只要應(yīng)用進(jìn)行了限流,那么應(yīng)用所依賴的各種服務(wù)也都得到了保護(hù)。

分布式服務(wù)限流實(shí)戰(zhàn),已經(jīng)為你排好坑了 | 總結(jié)的很全面

但線上業(yè)務(wù)出于各種原因考慮,多是分布式系統(tǒng),單節(jié)點(diǎn)的限流僅能保護(hù)自身節(jié)點(diǎn),但無法保護(hù)應(yīng)用依賴的各種服務(wù),并且在進(jìn)行節(jié)點(diǎn)擴(kuò)容、縮容時(shí)也無法準(zhǔn)確控制整個(gè)服務(wù)的請求限制。

分布式服務(wù)限流實(shí)戰(zhàn),已經(jīng)為你排好坑了 | 總結(jié)的很全面

而如果實(shí)現(xiàn)了分布式限流,那么就可以方便地控制整個(gè)服務(wù)集群的請求限制,且由于整個(gè)集群的請求數(shù)量得到了限制,因此服務(wù)依賴的各種資源也得到了限流的保護(hù)。

三、限流的算法

實(shí)現(xiàn)限流有很多辦法,在程序中時(shí)通常是根據(jù)每秒處理的事務(wù)數(shù)(Transaction per second)來衡量接口的流量。

本文介紹幾種最常用的限流算法:

  • 固定窗口計(jì)數(shù)器;

  • 滑動(dòng)窗口計(jì)數(shù)器;

  • 漏桶;

  • 令牌桶。

1、固定窗口計(jì)數(shù)器算法

分布式服務(wù)限流實(shí)戰(zhàn),已經(jīng)為你排好坑了 | 總結(jié)的很全面

固定窗口計(jì)數(shù)器算法概念如下:

  • 將時(shí)間劃分為多個(gè)窗口;

  • 在每個(gè)窗口內(nèi)每有一次請求就將計(jì)數(shù)器加一;

  • 如果計(jì)數(shù)器超過了限制數(shù)量,則本窗口內(nèi)所有的請求都被丟棄當(dāng)時(shí)間到達(dá)下一個(gè)窗口時(shí),計(jì)數(shù)器重置。

固定窗口計(jì)數(shù)器是最為簡單的算法,但這個(gè)算法有時(shí)會(huì)讓通過請求量允許為限制的兩倍??紤]如下情況:限制1秒內(nèi)最多通過5個(gè)請求,在第一個(gè)窗口的最后半秒內(nèi)通過了5個(gè)請求,第二個(gè)窗口的前半秒內(nèi)又通過了5個(gè)請求。這樣看來就是在1秒內(nèi)通過了10個(gè)請求。

分布式服務(wù)限流實(shí)戰(zhàn),已經(jīng)為你排好坑了 | 總結(jié)的很全面

2、滑動(dòng)窗口計(jì)數(shù)器算法

分布式服務(wù)限流實(shí)戰(zhàn),已經(jīng)為你排好坑了 | 總結(jié)的很全面

滑動(dòng)窗口計(jì)數(shù)器算法概念如下:

  • 將時(shí)間劃分為多個(gè)區(qū)間;

  • 在每個(gè)區(qū)間內(nèi)每有一次請求就將計(jì)數(shù)器加一維持一個(gè)時(shí)間窗口,占據(jù)多個(gè)區(qū)間;

  • 每經(jīng)過一個(gè)區(qū)間的時(shí)間,則拋棄最老的一個(gè)區(qū)間,并納入最新的一個(gè)區(qū)間;

  • 如果當(dāng)前窗口內(nèi)區(qū)間的請求計(jì)數(shù)總和超過了限制數(shù)量,則本窗口內(nèi)所有的請求都被丟棄。

滑動(dòng)窗口計(jì)數(shù)器是通過將窗口再細(xì)分,并且按照時(shí)間"滑動(dòng)",這種算法避免了固定窗口計(jì)數(shù)器帶來的雙倍突發(fā)請求,但時(shí)間區(qū)間的精度越高,算法所需的空間容量就越大。

3、漏桶算法

分布式服務(wù)限流實(shí)戰(zhàn),已經(jīng)為你排好坑了 | 總結(jié)的很全面

漏桶算法概念如下:

  • 將每個(gè)請求視作"水滴"放入"漏桶"進(jìn)行存儲(chǔ);

  • "漏桶"以固定速率向外"漏"出請求來執(zhí)行如果"漏桶"空了則停止"漏水";

  • 如果"漏桶"滿了則多余的"水滴"會(huì)被直接丟棄。

漏桶算法多使用隊(duì)列實(shí)現(xiàn),服務(wù)的請求會(huì)存到隊(duì)列中,服務(wù)的提供方則按照固定的速率從隊(duì)列中取出請求并執(zhí)行,過多的請求則放在隊(duì)列中排隊(duì)或直接拒絕。

漏桶算法的缺陷也很明顯,當(dāng)短時(shí)間內(nèi)有大量的突發(fā)請求時(shí),即便此時(shí)服務(wù)器沒有任何負(fù)載,每個(gè)請求也都得在隊(duì)列中等待一段時(shí)間才能被響應(yīng)。

4、令牌桶算法

分布式服務(wù)限流實(shí)戰(zhàn),已經(jīng)為你排好坑了 | 總結(jié)的很全面

令牌桶算法概念如下:

  • 令牌以固定速率生成;

  • 生成的令牌放入令牌桶中存放,如果令牌桶滿了則多余的令牌會(huì)直接丟棄,當(dāng)請求到達(dá)時(shí),會(huì)嘗試從令牌桶中取令牌,取到了令牌的請求可以執(zhí)行;

  • 如果桶空了,那么嘗試取令牌的請求會(huì)被直接丟棄。

令牌桶算法既能夠?qū)⑺械恼埱笃骄植嫉綍r(shí)間區(qū)間內(nèi),又能接受服務(wù)器能夠承受范圍內(nèi)的突發(fā)請求,因此是目前使用較為廣泛的一種限流算法。

四、代碼實(shí)現(xiàn)

作為如此重要的功能,在Java中自然有很多實(shí)現(xiàn)限流的類庫,例如Google的開源項(xiàng)目guava提供了RateLimiter類,實(shí)現(xiàn)了單點(diǎn)的令牌桶限流。

而分布式限流常用的則有Hystrix、resilience4j、Sentinel等框架,但這些框架都需引入第三方的類庫,對于國企等一些保守的企業(yè),引入外部類庫都需要經(jīng)過層層審批,較為麻煩。

分布式限流本質(zhì)上是一個(gè)集群并發(fā)問題,而Redis作為一個(gè)應(yīng)用廣泛的中間件,又擁有單進(jìn)程單線程的特性,天然可以解決分布式集群的并發(fā)問題。本文簡單介紹一個(gè)通過Redis實(shí)現(xiàn)單次請求判斷限流的功能。

1、腳本編寫

經(jīng)過上面的對比,最適合的限流算法就是令牌桶算法。而為實(shí)現(xiàn)限流算法,需要反復(fù)調(diào)用Redis查詢與計(jì)算,一次限流判斷需要多次請求較為耗時(shí)。因此我們采用編寫Lua腳本運(yùn)行的方式,將運(yùn)算過程放在Redis端,使得對Redis進(jìn)行一次請求就能完成限流的判斷。

令牌桶算法需要在Redis中存儲(chǔ)桶的大小、當(dāng)前令牌數(shù)量,并且實(shí)現(xiàn)每隔一段時(shí)間添加新的令牌。最簡單的辦法當(dāng)然是每隔一段時(shí)間請求一次Redis,將存儲(chǔ)的令牌數(shù)量遞增。

但實(shí)際上我們可以通過對限流兩次請求之間的時(shí)間和令牌添加速度來計(jì)算得出上次請求之后到本次請求時(shí),令牌桶應(yīng)添加的令牌數(shù)量。因此我們在Redis中只需要存儲(chǔ)上次請求的時(shí)間和令牌桶中的令牌數(shù)量,而桶的大小和令牌的添加速度可以通過參數(shù)傳入實(shí)現(xiàn)動(dòng)態(tài)修改。

由于第一次運(yùn)行腳本時(shí)默認(rèn)令牌桶是滿的,因此可以將數(shù)據(jù)的過期時(shí)間設(shè)置為令牌桶恢復(fù)到滿所需的時(shí)間,及時(shí)釋放資源。

編寫完成的Lua腳本如下:

分布式服務(wù)限流實(shí)戰(zhàn),已經(jīng)為你排好坑了 | 總結(jié)的很全面

2、執(zhí)行限流

這里使用Spring Data Redis來進(jìn)行Redis腳本的調(diào)用。

編寫Redis腳本類:

分布式服務(wù)限流實(shí)戰(zhàn),已經(jīng)為你排好坑了 | 總結(jié)的很全面

通過RedisTemplate對象執(zhí)行腳本:

分布式服務(wù)限流實(shí)戰(zhàn),已經(jīng)為你排好坑了 | 總結(jié)的很全面

rateLimit方法傳入的key為限流接口的ID,max為令牌桶的大大小,rate為每秒鐘恢復(fù)的令牌數(shù)量,返回的boolean即為此次請求是否通過了限流。為了測試Redis腳本限流是否可以正常工作,我們編寫一個(gè)單元測試進(jìn)行測試看看。

分布式服務(wù)限流實(shí)戰(zhàn),已經(jīng)為你排好坑了 | 總結(jié)的很全面

設(shè)置令牌桶大小為10,令牌桶每秒恢復(fù)10個(gè),啟動(dòng)10個(gè)線程在短時(shí)間內(nèi)進(jìn)行30次請求,并輸出每次限流查詢的結(jié)果。日志輸出:

分布式服務(wù)限流實(shí)戰(zhàn),已經(jīng)為你排好坑了 | 總結(jié)的很全面

可以看到,在0.1秒內(nèi)請求的30次請求中,除了初始的10個(gè)令牌以及隨時(shí)間恢復(fù)的1個(gè)令牌外,剩下19個(gè)沒有取得令牌的請求均返回了false,限流腳本正確的將超過限制的請求給判斷出來了,業(yè)務(wù)中此時(shí)就可以直接返回系統(tǒng)繁忙或接口請求太過頻繁等提示。

3、開發(fā)中遇到的問題

1)Lua變量格式

Lua中的String和Number需要通過tonumber()和tostring()進(jìn)行轉(zhuǎn)換。

2)Redis入?yún)?/p>

Redis的pexpire等命令不支持小數(shù),但Lua的Number類型可以存放小數(shù),因此Number類型傳遞給 Redis時(shí)最好通過math.ceil()等方式轉(zhuǎn)換以避免存在小數(shù)導(dǎo)致命令失敗。

3)Time命令

由于Redis在集群下是通過復(fù)制腳本及參數(shù)到所有節(jié)點(diǎn)上,因此無法在具有不確定性的命令后面執(zhí)行寫入命令,因此只能請求時(shí)傳入時(shí)間而無法使用Redis的Time命令獲取時(shí)間。

3.2版本之后的Redis腳本支持redis.replicate_commands(),可以改為使用Time命令獲取當(dāng)前時(shí)間。

4)潛在的隱患

由于此Lua腳本是通過請求時(shí)傳入的時(shí)間做計(jì)算,因此務(wù)必保證分布式節(jié)點(diǎn)上獲取的時(shí)間同步,如果時(shí)間不同步會(huì)導(dǎo)致限流無法正常運(yùn)作。

歡迎工作一到五年的Java工程師朋友們加入我的個(gè)人粉絲群Java填坑之路:659655594群內(nèi)提供免費(fèi)的Java架構(gòu)學(xué)習(xí)資料(里面有高可用、高并發(fā)、高性能及分布式、Jvm性能調(diào)優(yōu)、Spring源碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個(gè)知識(shí)點(diǎn)的架構(gòu)資料)

合理利用自己每一分每一秒的時(shí)間來學(xué)習(xí)提升自己,不要再用"沒有時(shí)間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個(gè)交代!

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

網(wǎng)站欄目:分布式服務(wù)限流實(shí)戰(zhàn),已經(jīng)為你排好坑了|總結(jié)的很全面-創(chuàng)新互聯(lián)
分享地址:http://jinyejixie.com/article44/cccjhe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計(jì)、外貿(mào)建站電子商務(wù)、動(dòng)態(tài)網(wǎng)站、虛擬主機(jī)、微信公眾號(hào)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)
长子县| 萝北县| 沙洋县| 旌德县| 正定县| 淮安市| 合川市| 喀什市| 仙居县| 怀远县| 海林市| 鹤峰县| 栾川县| 安远县| 司法| 凌源市| 固阳县| 平定县| 若尔盖县| 西安市| 汕尾市| 清徐县| 绿春县| 泰来县| 嘉鱼县| 阜新市| 普宁市| 太仓市| 新密市| 秦皇岛市| 内乡县| 阳西县| 县级市| 钦州市| 陵水| 黄浦区| 乌兰浩特市| 弥勒县| 平舆县| 宁海县| 高碑店市|