<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>

          面試官:說(shuō)一下海量請(qǐng)求下的接口并發(fā)解決方案

          共 3331字,需瀏覽 7分鐘

           ·

          2022-11-29 12:20

          關(guān)注我們,設(shè)為星標(biāo),每天7:40不見不散,架構(gòu)路上與您共享

          回復(fù)架構(gòu)師獲取資源


          大家好,我是你們的朋友架構(gòu)君,一個(gè)會(huì)寫代碼吟詩(shī)的架構(gòu)師。

          'javajgs.com';


          原文:
          blog.csdn.net/weixin_44414492/article/details/123027974


          設(shè)定一個(gè)場(chǎng)景,假如一個(gè)商品接口在某段時(shí)間突然上升,會(huì)怎么辦?

          生活中的例子來(lái)說(shuō),假設(shè)冰墩墩在當(dāng)天晚上上熱搜之后,迅速有十幾萬(wàn)人去淘寶下單購(gòu)買,此時(shí)并沒(méi)有做好對(duì)該商品的緩存預(yù)熱以及準(zhǔn)備,如何操作?

          對(duì)于這個(gè)問(wèn)題,在電商高并發(fā)系統(tǒng)中,對(duì)接口的保護(hù)一般采用:緩存、限流、降級(jí) 來(lái)操作。


          假設(shè)該接口已經(jīng)接受過(guò)風(fēng)控的處理,過(guò)濾掉一半的機(jī)器人腳本請(qǐng)求,剩下都是人為的下單請(qǐng)求。


          服務(wù)限流


          限流 主要的目的是通過(guò)對(duì)并發(fā)訪問(wèn)/請(qǐng)求進(jìn)行限速,或者對(duì)一個(gè)時(shí)間窗口內(nèi)的請(qǐng)求進(jìn)行限速,一旦達(dá)到限制速率則可以拒絕服務(wù)、排隊(duì)或等待、降級(jí)等處理。


          限流算法

          1. 漏斗算法

          漏桶算法 是當(dāng)請(qǐng)求到達(dá)時(shí)直接放入漏桶,如果當(dāng)前容量已達(dá)到上限(限流值),則進(jìn)行丟棄或其他策略(觸發(fā)限流策略)。漏桶以固定的速率(根據(jù)服務(wù)吞吐量)進(jìn)行釋放訪問(wèn)請(qǐng)求(即請(qǐng)求通過(guò)),直到漏桶為空。

          漏斗算法的思想就是,不管你來(lái)多少請(qǐng)求,我的接口消費(fèi)速度一定是小于等于流出速率的閾值的。

          可以基于消息隊(duì)列來(lái)實(shí)現(xiàn)。

          2. 令牌桶算法

          令牌桶算法 是程序以v(v = 時(shí)間周期 / 限流值)的速度向令牌桶中增加令牌,直到令牌桶滿,請(qǐng)求到達(dá)時(shí)向令牌桶請(qǐng)求令牌,如果獲取成功則通過(guò)請(qǐng)求,如果獲取失敗觸發(fā)限流策略。

          令牌桶算法和漏斗算法的思想差別在于,前者可以允許突發(fā)請(qǐng)求的發(fā)生。

          3. 滑窗算法

          滑窗算法 是將一個(gè)時(shí)間周期分為N個(gè)小周期,分別記錄每個(gè)小周期內(nèi)訪問(wèn)次數(shù),并且根據(jù)時(shí)間滑動(dòng)刪除過(guò)期的小周期。

          如下圖所示,假設(shè)時(shí)間周期為1分鐘,將1分鐘再分為2個(gè)小周期,統(tǒng)計(jì)每個(gè)小周期的訪問(wèn)數(shù)量,則可以看到,第一個(gè)時(shí)間周期內(nèi),訪問(wèn)數(shù)量為75,第二個(gè)時(shí)間周期內(nèi),訪問(wèn)數(shù)量為100,如果一個(gè)時(shí)間周期內(nèi)所有的小周期總和超過(guò)100的話,則會(huì)觸發(fā)限流策略。

          Sentinel的實(shí)現(xiàn) 和 TCP滑窗。


          接入層限流

          Nginx限流

          Nginx 限流采用的是漏桶算法。

          它可以根據(jù)客戶端特征,限制其訪問(wèn)頻率,客戶端特征主要指 IP、UserAgent等。使用 IP 比 UserAgent 更可靠,因?yàn)?IP 無(wú)法造假,UserAgent 可隨意偽造。

          limit_req模塊基于IP:

          http://nginx.org/en/docs/http/ngx_http_limit_req_module.html

          tgngine:

          http://tengine.taobao.org/document_cn/http_limit_req_cn.html


          本地接口限流

          Semaphore

          Java 并發(fā)庫(kù) 的 Semaphore 可以很輕松完成信號(hào)量控制,Semaphore 可以控制某個(gè)資源可被同時(shí)訪問(wèn)的個(gè)數(shù),通過(guò) acquire() 獲取一個(gè)許可,如果沒(méi)有就等待,而 release() 釋放一個(gè)許可。

          假如我們對(duì)外提供一個(gè)服務(wù)接口,允許最大并發(fā)數(shù)為40,我們可以這樣:

          private final Semaphore permit = new Semaphore(40true);

          public void process(){

              try{
                  permit.acquire();
                  //TODO 處理業(yè)務(wù)邏輯

              } catch (InterruptedException e) {
                  e.printStackTrace();
              } finally {
                  permit.release();
              }
          }

          具體的 Semaphore 實(shí)現(xiàn)參考源碼。


          分布式接口限流

          使用消息隊(duì)列

          不管是用MQ中間件,或是Redis的List實(shí)現(xiàn)的消息隊(duì)列,都可以作為一個(gè) 緩沖隊(duì)列 來(lái)使用。思想就是基于漏斗算法。

          當(dāng)對(duì)于一個(gè)接口請(qǐng)求達(dá)到一定閾值時(shí),就可以啟用消息隊(duì)列來(lái)進(jìn)行接口數(shù)據(jù)的緩沖,并根據(jù)服務(wù)的吞吐量來(lái)消費(fèi)數(shù)據(jù)。

          服務(wù)降級(jí)


          在接口做好風(fēng)控的前提下,發(fā)現(xiàn)了接口請(qǐng)求的并發(fā)量迅速上升,我們可以啟用兜底方案,進(jìn)行服務(wù)降級(jí)。

          一般服務(wù)降級(jí)應(yīng)該用來(lái)對(duì)一些 不重要 或 不緊急 的服務(wù)或任務(wù)進(jìn)行服務(wù)的 延遲使用 或 暫停使用。


          降級(jí)方案

          停止邊緣業(yè)務(wù)

          比如淘寶雙11前,就不可以查詢?nèi)齻€(gè)月前的訂單,對(duì)邊緣業(yè)務(wù)進(jìn)行降級(jí),保證核心業(yè)務(wù)的高可用。

          拒絕請(qǐng)求

          在接口請(qǐng)求并發(fā)量大于閾值,或是接口出現(xiàn)大量失敗請(qǐng)求等等突發(fā)情況,可以拒絕一些訪問(wèn)請(qǐng)求。

          拒絕策略
          • 隨機(jī)拒絕:隨機(jī)拒絕超過(guò)閾值的請(qǐng)求 。
          • 拒絕舊請(qǐng)求:按照請(qǐng)求的時(shí)間,優(yōu)先拒絕更早收到的請(qǐng)求。
          • 拒絕非核心請(qǐng)求:根據(jù)系統(tǒng)業(yè)務(wù)設(shè)置核心請(qǐng)求清單,將非核心清單內(nèi)的請(qǐng)求拒絕掉。
          恢復(fù)方案

          在實(shí)現(xiàn)服務(wù)降級(jí)之后,對(duì)于突增流量我們可以繼續(xù)注冊(cè)多個(gè)消費(fèi)者服務(wù)來(lái)應(yīng)對(duì)并發(fā)量,之后我們?cè)賹?duì)一些服務(wù)器進(jìn)行慢加載。

          降級(jí)具體實(shí)現(xiàn)參考其他文章。


          數(shù)據(jù)緩存


          在接口做好風(fēng)控的前提下,發(fā)現(xiàn)了接口請(qǐng)求的并發(fā)量迅速上升,我們可以分以下幾個(gè)操作執(zhí)行:

          • 對(duì)訪問(wèn)請(qǐng)求使用分布式鎖進(jìn)行阻塞。
          • 在這個(gè)短時(shí)間中,我們可以將對(duì)應(yīng)操作行的熱點(diǎn)數(shù)據(jù),緩存在緩存中間件中。
          • 放行請(qǐng)求后,讓所有請(qǐng)求優(yōu)先操作緩存數(shù)據(jù)。
          • 再將操作的結(jié)果通過(guò)消息隊(duì)列發(fā)送給消費(fèi)接口慢慢消費(fèi)。


          緩存問(wèn)題


          假設(shè)我們操作的是一個(gè)庫(kù)存接口,此時(shí)數(shù)據(jù)庫(kù)中只有100個(gè)庫(kù)存。

          那假如此時(shí)我們將一條數(shù)據(jù)放入緩存中,如果所有的請(qǐng)求都來(lái)訪問(wèn)這個(gè)緩存,那它還是被打掛,我們?cè)撛趺床僮鳎?/span>

          讀寫分離

          第一種想法,讀寫分離。

          使用Redis的哨兵集群模式來(lái)進(jìn)行主從復(fù)制的讀寫分離操作。讀的操作肯定大于寫操作,等庫(kù)存被消費(fèi)到0時(shí),讀操作直接快速失敗。

          負(fù)載均衡

          第二種想法,負(fù)載均衡。

          在緩存數(shù)據(jù)后,如果所有請(qǐng)求都來(lái)緩存中操作這個(gè)庫(kù)存,不管是加悲觀鎖還是樂(lè)觀鎖,并發(fā)率都很低,此時(shí)我們可以對(duì)這個(gè)庫(kù)存進(jìn)行拆分。

          我們可以參照 ConcurrentHashMap 中的 counterCells 變量的設(shè)計(jì)思想,將100個(gè)庫(kù)存拆分到10個(gè)緩存服務(wù)中,每個(gè)緩存服務(wù)有10個(gè)緩存,然后我們?cè)賹?duì)請(qǐng)求進(jìn)行負(fù)載均衡到各個(gè)緩存服務(wù)上。

          但是這種方式會(huì)有問(wèn)題,如果大部分用戶被hash到同一個(gè)緩存上,導(dǎo)致其他緩存沒(méi)有被消費(fèi),卻返回沒(méi)有庫(kù)存,這是不合理的。

          page cache

          第三種想法,page cache。

          大部分軟件架構(gòu)其實(shí)都用到了這種方法,比如linux內(nèi)核的硬盤寫入、mysql的刷盤等等,即將短時(shí)間內(nèi)的寫操作聚合結(jié)果寫入,所有的寫操作在緩存內(nèi)完成。


          到此文章就結(jié)束了。Java架構(gòu)師必看一個(gè)集公眾號(hào)、小程序、網(wǎng)站(3合1的文章平臺(tái),給您架構(gòu)路上一臂之力,javajgs.com)。如果今天的文章對(duì)你在進(jìn)階架構(gòu)師的路上有新的啟發(fā)和進(jìn)步,歡迎轉(zhuǎn)發(fā)給更多人。歡迎加入架構(gòu)師社區(qū)技術(shù)交流群,眾多大咖帶你進(jìn)階架構(gòu)師,在后臺(tái)回復(fù)“加群”即可入群。

          第23期已結(jié)束!第24期已開始,11月1號(hào)截止



          這些年小編給你分享過(guò)的干貨


          1.idea永久激活碼(親測(cè)可用)

          2.優(yōu)質(zhì)ERP系統(tǒng)帶進(jìn)銷存財(cái)務(wù)生產(chǎn)功能(附源碼)

          3.優(yōu)質(zhì)SpringBoot帶工作流管理項(xiàng)目(附源碼)

          4.最好用的OA系統(tǒng),拿來(lái)即用(附源碼)

          5.SBoot+Vue外賣系統(tǒng)前后端都有(附源碼

          6.SBoot+Vue可視化大屏拖拽項(xiàng)目(附源碼)


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

          瀏覽 40
          點(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>
                  亚洲高清视频在线观看在线观看 | 午夜无码视频 | 国产麻豆成人传媒免费观看 | 一区二区三区永久网 | 免费操逼网站 |