国产一级一区二区_segui88久久综合9999_97久久夜色精品国产_欧美色网一区二区

掃一掃
關注微信公眾號

96秒100億!如何抗住雙11高并發流量?
2019-11-12   博客園 邴越

今年雙 11 全民購物狂歡節進入第十一個年頭,1 分 36 秒,交易額沖到 100 億 !比 2018 年快了近 30 秒,比 2017 年快了近 1 分半!這個速度再次刷新天貓雙 11 成交總額破 100 億的紀錄。


圖片來自 Pexels

那么如何抗住雙 11 高并發流量?接下來讓我們一起來聊聊高可用的“大殺器”限流降級技術。

服務等級協議

我們常說的 N 個 9,就是對 SLA 的一個描述。SLA 全稱是 Service Level Agreement,翻譯為服務水平協議,也稱服務等級協議,它表明了公有云提供服務的等級以及質量。

例如阿里云對外承諾的就是一個服務周期內集群服務可用性不低于 99.99%,如果低于這個標準,云服務公司就需要賠償客戶的損失。

做到 4 個 9 夠好了嗎

對互聯網公司來說,SLA 就是網站或者 API 服務可用性的一個保證。

9 越多代表全年服務可用時間越長服務更可靠,4 個 9 的服務可用性,聽起來已經很高了,但對于實際的業務場景,這個值可能并不夠。

我們來做一個簡單的計算,假設一個核心鏈路依賴 20 個服務,強依賴同時沒有配置任何降級,并且這 20 個服務的可用性達到 4 個 9,也就是 99.99%。

那這個核心鏈路的可用性只有 99.99 的 20 次方=99.8%,如果有 10 億次請求則有 3,000,000 次的失敗請求,理想狀況下,每年還是有 17 小時服務不可用。

這是一個理想的估算,在實際的生產環境中,由于服務發布,宕機等各種各樣的原因,情況肯定會比這個更差。

對于一些比較敏感的業務,比如金融,或是對服務穩定要求較高的行業,比如訂單或者支付業務,這樣的情況是不能接受的。

微服務的雪崩效應

除了對服務可用性的追求,微服務架構一個繞不過去的問題就是服務雪崩。

在一個調用鏈路上,微服務架構各個服務之間組成了一個松散的整體,牽一發而動全身,服務雪崩是一個多級傳導的過程。

首先是某個服務提供者不可用,由于大量超時等待,繼而導致服務調用者不可用,并且在整個鏈路上傳導,繼而導致系統癱瘓。

限流降級怎么做

如同上面我們分析的,在大規模微服務架構的場景下,避免服務出現雪崩,要減少停機時間,要盡可能的提高服務可用性。

提高服務可用性,可以從很多方向入手,比如緩存、池化、異步化、負載均衡、隊列和降級熔斷等手段。

緩存以及隊列等手段,增加系統的容量。限流和降級則是關心在到達系統瓶頸時系統的響應,更看重穩定性。

緩存和異步等提高系統的戰力,限流降級關注的是防御。限流和降級,具體實施方法可以歸納為八字箴言,分別是限流,降級,熔斷和隔離。

限流和降級

限流顧名思義,提前對各個類型的請求設置最高的 QPS 閾值,若高于設置的閾值則對該請求直接返回,不再調用后續資源。

限流需要結合壓測等,了解系統的最高水位,也是在實際開發中應用最多的一種穩定性保障手段。

降級則是當服務器壓力劇增的情況下,根據當前業務情況及流量對一些服務和頁面有策略的降級,以此釋放服務器資源以保證核心任務的正常運行。

從降級配置方式上,降級一般可以分為主動降級和自動降級。主動降級是提前配置,自動降級則是系統發生故障時,如超時或者頻繁失敗,自動降級。

其中,自動降級,又可以分為以下策略:

  • 超時降級
  • 失敗次數降級
  • 故障降級

在系統設計中,降級一般是結合系統配置中心,通過配置中心進行推送,下面是一個典型的降級通知設計。

熔斷隔離

如果某個目標服務調用慢或者有大量超時,此時熔斷該服務的調用,對于后續調用請求,不在繼續調用目標服務,直接返回,快速釋放資源。

熔斷一般需要設置不同的恢復策略,如果目標服務情況好轉則恢復調用。

服務隔離與前面的三個略有區別,我們的系統通常提供了不止一個服務,但是這些服務在運行時是部署在一個實例,或者一臺物理機上面的。

如果不對服務資源做隔離,一旦一個服務出現了問題,整個系統的穩定性都會受到影響!服務隔離的目的就是避免服務之間相互影響。

一般來說,隔離要關注兩方面,一個是在哪里進行隔離,另外一個是隔離哪些資源。

何處隔離:一次服務調用,涉及到的是服務提供方和調用方,我們所指的資源,也是兩方的服務器等資源,服務隔離通常可以從提供方和調用方兩個方面入手。

隔離什么:廣義的服務隔離,不僅包括服務器資源,還包括數據庫分庫,緩存,索引等,這里我們只關注服務層面的隔離。

降級和熔斷的區別

服務降級和熔斷在概念上比較相近,通過兩個場景,談談我自己的理解。

熔斷,一般是停止服務:典型的就是股市的熔斷,如果大盤不受控制,直接休市,不提供服務,是保護大盤的一種方式。

降級,通常是有備用方案:從北京到濟南,下雨導致航班延誤,我可以乘坐高鐵,如果高鐵票買不到,也可以乘坐汽車或者開車過去。

兩者的區別:降級一般是主動的,有預見性的,熔斷通常是被動的,服務 A 降級以后,一般會有服務 B 來代替,而熔斷通常是針對核心鏈路的處理。

在實際開發中,熔斷的下一步通常就是降級。

常用限流算法設計

剛才講了限流的概念,那么怎樣判斷系統到達設置的流量閾值了?這就需要一些限流策略來支持,不同的限流算法有不同的特點,平滑程度也不同。

計數器法

計數器法是限流算法里最簡單也是最容易實現的一種算法。

假設一個接口限制一分鐘內的訪問次數不能超過 100 個,維護一個計數器,每次有新的請求過來,計數器加一。

這時候判斷,如果計數器的值小于限流值,并且與上一次請求的時間間隔還在一分鐘內,允許請求通過,否則拒絕請求,如果超出了時間間隔,要將計數器清零。


  1. public class CounterLimiter { 
  2.  
  3.     //初始時間 
  4.     private static long startTime = System.currentTimeMillis(); 
  5.  
  6.     //初始計數值 
  7.     private static final AtomicInteger ZERO = new AtomicInteger(0); 
  8.  
  9.     //時間窗口限制 
  10.     private static final long interval = 10000; 
  11.  
  12.     //限制通過請求 
  13.     private static int limit = 100; 
  14.  
  15.     //請求計數 
  16.     private AtomicInteger requestCount = ZERO; 
  17.  
  18.     //獲取限流 
  19.     public boolean tryAcquire() { 
  20.  
  21.         long now = System.currentTimeMillis(); 
  22.  
  23.         //在時間窗口內 
  24.         if (now < startTime + interval) { 
  25.  
  26.             //判斷是否超過最大請求 
  27.             if (requestCount.get() < limit) { 
  28.                 requestCount.incrementAndGet(); 
  29.                 return true
  30.             } 
  31.             return false
  32.  
  33.         } else { 
  34.  
  35.             //超時重置 
  36.             startTime = now; 
  37.             requestCount = ZERO; 
  38.             return true
  39.         } 
  40.  
  41.     } 

計數器限流可以比較容易的應用在分布式環境中,用一個單點的存儲來保存計數值,比如用 Redis,并且設置自動過期時間,這時候就可以統計整個集群的流量,并且進行限流。

計數器方式的缺點是不能處理臨界問題,或者說限流策略不夠平滑。

假設在限流臨界點的前后,分別發送 100 個請求,實際上在計數器置 0 前后的極短時間里,處理了 200 個請求,這是一個瞬時的高峰,可能會超過系統的限制。

計數器限流允許出現 2*permitsPerSecond 的突發流量,可以使用滑動窗口算法去優化,具體不展開。

漏桶算法

假設我們有一個固定容量的桶,桶底部可以漏水(忽略氣壓等,不是物理問題),并且這個漏水的速率可控的,那么我們可以通過這個桶來控制請求速度,也就是漏水的速度。

我們不關心流進來的水,也就是外部請求有多少,桶滿了之后,多余的水會溢出。

漏桶算法的示意圖如下:

將算法中的水換成實際應用中的請求,可以看到漏桶算法從入口限制了請求的速度。

使用漏桶算法,我們可以保證接口會以一個常速速率來處理請求,所以漏桶算法不會出現臨界問題。

這里簡單實現一下,也可以使用 Guava 的 SmoothWarmingUp 類,可以更好的控制漏桶算法:


  1. public class LeakyLimiter { 
  2.  
  3.     //桶的容量 
  4.     private int capacity; 
  5.  
  6.     //漏水速度 
  7.     private int ratePerMillSecond; 
  8.  
  9.     //水量 
  10.     private double water; 
  11.  
  12.     //上次漏水時間 
  13.     private long lastLeakTime; 
  14.  
  15.     public LeakyLimiter(int capacity, int ratePerMillSecond) { 
  16.  
  17.         this.capacity = capacity; 
  18.         this.ratePerMillSecond = ratePerMillSecond; 
  19.         this.water = 0; 
  20.     } 
  21.  
  22.  
  23.     //獲取限流 
  24.     public boolean tryAcquire() { 
  25.  
  26.         //執行漏水,更新剩余水量 
  27.         refresh(); 
  28.  
  29.         //嘗試加水,水滿則拒絕 
  30.         if (water + 1 > capacity) { 
  31.             return false
  32.         } 
  33.  
  34.         water = water + 1; 
  35.         return true
  36.  
  37.     } 
  38.  
  39.     private void refresh() { 
  40.         //當前時間 
  41.         long currentTime = System.currentTimeMillis(); 
  42.  
  43.         if (currentTime > lastLeakTime) { 
  44.  
  45.             //距上次漏水的時間間隔 
  46.             long millisSinceLastLeak = currentTime - lastLeakTime; 
  47.             long leaks = millisSinceLastLeak * ratePerMillSecond; 
  48.  
  49.             //允許漏水 
  50.             if (leaks > 0) { 
  51.                 //已經漏光 
  52.                 if (water <= leaks) { 
  53.                     water = 0; 
  54.                 } else { 
  55.                     water = water - leaks; 
  56.                 } 
  57.                 this.lastLeakTime = currentTime; 
  58.             } 
  59.         } 
  60.     } 

令牌桶算法

漏桶是控制水流入的速度,令牌桶則是控制留出,通過控制 Token,調節流量。

假設一個大小恒定的桶,桶里存放著令牌(Token)。桶一開始是空的,現在以一個固定的速率往桶里填充,直到達到桶的容量,多余的令牌將會被丟棄。

如果令牌不被消耗,或者被消耗的速度小于產生的速度,令牌就會不斷地增多,直到把桶填滿。后面再產生的令牌就會從桶中溢出。

最后桶中可以保存的最大令牌數永遠不會超過桶的大小,每當一個請求過來時,就會嘗試從桶里移除一個令牌,如果沒有令牌的話,請求無法通過。


  1. public class TokenBucketLimiter { 
  2.  
  3.     private long capacity; 
  4.     private long windowTimeInSeconds; 
  5.     long lastRefillTimeStamp; 
  6.     long refillCountPerSecond; 
  7.     long availableTokens; 
  8.  
  9.     public TokenBucketLimiter(long capacity, long windowTimeInSeconds) { 
  10.         this.capacity = capacity; 
  11.         this.windowTimeInSeconds = windowTimeInSeconds; 
  12.         lastRefillTimeStamp = System.currentTimeMillis(); 
  13.         refillCountPerSecond = capacity / windowTimeInSeconds; 
  14.         availableTokens = 0; 
  15.     } 
  16.  
  17.     public long getAvailableTokens() { 
  18.         return this.availableTokens; 
  19.     } 
  20.  
  21.     public boolean tryAcquire() { 
  22.  
  23.         //更新令牌桶 
  24.         refill(); 
  25.  
  26.         if (availableTokens > 0) { 
  27.             --availableTokens; 
  28.             return true
  29.         } else { 
  30.             return false
  31.         } 
  32.     } 
  33.  
  34.  
  35.     private void refill() { 
  36.         long now = System.currentTimeMillis(); 
  37.  
  38.         if (now > lastRefillTimeStamp) { 
  39.  
  40.             long elapsedTime = now - lastRefillTimeStamp; 
  41.  
  42.             int tokensToBeAdded = (int) ((elapsedTime / 1000) * refillCountPerSecond); 
  43.  
  44.             if (tokensToBeAdded > 0) { 
  45.                 availableTokens = Math.min(capacity, availableTokens + tokensToBeAdded); 
  46.                 lastRefillTimeStamp = now; 
  47.             } 
  48.         } 
  49.     } 
  50.  

這兩種算法的主要區別在于漏桶算法能夠強行限制數據的傳輸速率,而令牌桶算法在能夠限制數據的平均傳輸速率外,還允許某種程度的突發傳輸。

在令牌桶算法中,只要令牌桶中存在令牌,那么就允許突發地傳輸數據直到達到用戶配置的門限,因此它適合于具有突發特性的流量。

漏桶和令牌桶的比較

漏桶和令牌桶算法實現可以一樣,但是方向是相反的,對于相同的參數得到的限流效果是一樣的。

主要區別在于令牌桶允許一定程度的突發,漏桶主要目的是平滑流入速率,考慮一個臨界場景,令牌桶內積累了 100 個 Token,可以在一瞬間通過。

但是因為下一秒產生 Token 的速度是固定的,所以令牌桶允許出現瞬間出現 permitsPerSecond 的流量,但是不會出現 2*permitsPerSecond 的流量,漏桶的速度則始終是平滑的。

使用 RateLimiter 實現限流

Google 開源工具包 Guava 提供了限流工具類 RateLimiter,該類基于令牌桶算法實現流量限制,使用方便。

RateLimiter 使用的是令牌桶的流控算法,RateLimiter 會按照一定的頻率往桶里扔令牌,線程拿到令牌才能執行。

比如你希望自己的應用程序 QPS 不要超過 1000,那么 RateLimiter 設置 1000 的速率后,就會每秒往桶里扔 1000 個令牌,看下方法的說明:

RateLimter 提供的 API 可以直接應用,其中 acquire 會阻塞,類似 JUC 的信號量 Semphore,tryAcquire 方法則是非阻塞的:


  1. public class RateLimiterTest { 
  2.  
  3.     public static void main(String[] args) throws InterruptedException { 
  4.  
  5.         //允許10個,permitsPerSecond 
  6.         RateLimiter limiter = RateLimiter.create(10); 
  7.  
  8.         for(int i=1;i<20;i++){ 
  9.             if (limiter.tryAcquire(1)){ 
  10.                 System.out.println("第"+i+"次請求成功"); 
  11.             }else
  12.                 System.out.println("第"+i+"次請求拒絕"); 
  13.             } 
  14.         } 
  15.     } 

總結

本文從服務可用性開始,分析了在業務高峰期通過限流降級保障服務高可用的重要性。

接下來分別探討了限流,降級,熔斷,隔離的概念和應用,并且介紹了常用的限流策略。

作者:邴越

簡介:某電商平臺架構師,曾任阿里巴巴中臺資深開發工程師,云棲社區專家,關注分布式系統和高可用架構。

熱詞搜索:大數據 雙11

上一篇:海克斯康助力漢莎航空實現實時數據可視化
下一篇:大數據品牌戰略的關鍵要素

分享到: 收藏
国产一级一区二区_segui88久久综合9999_97久久夜色精品国产_欧美色网一区二区
精品噜噜噜噜久久久久久久久试看| 亚洲精品一区二区精华| 精品日本一线二线三线不卡| 午夜久久久久久| 欧美日韩国产一级片| 激情久久五月天| 一区二区三区在线观看国产| 欧美成人三级电影在线| 成人一区二区在线观看| 日韩不卡一区二区三区| 国产精品久久久久四虎| 欧美一三区三区四区免费在线看| 国产成人在线色| 天堂va蜜桃一区二区三区漫画版| 国产精品色哟哟网站| 欧美一区午夜精品| 欧美三级日韩三级| 91免费观看国产| 国产福利电影一区二区三区| 日韩激情在线观看| 亚洲素人一区二区| 制服丝袜一区二区三区| 日本高清视频一区二区| 懂色av一区二区夜夜嗨| 国产美女在线观看一区| 视频一区中文字幕国产| 亚洲色图.com| 亚洲天堂av老司机| 中文字幕一区二区三区不卡在线| 精品国产露脸精彩对白| 欧美在线免费视屏| 色综合天天做天天爱| 懂色av中文一区二区三区| 国产综合一区二区| 免费欧美在线视频| 国产精品三级av在线播放| 国产欧美日韩在线| 久久久精品欧美丰满| 欧美日韩成人综合| 欧美日韩精品一区二区三区| 日本高清不卡视频| 99精品国产一区二区三区不卡| 国产91清纯白嫩初高中在线观看| 免费观看30秒视频久久| 亚洲成人一区二区在线观看| 亚洲一区中文日韩| 最新成人av在线| 亚洲同性gay激情无套| 欧美三级在线视频| 欧美性大战久久久| 欧美美女喷水视频| 69堂精品视频| 日韩欧美卡一卡二| 26uuu国产日韩综合| 亚洲精品一区二区三区99| 欧美xxxxx裸体时装秀| 91精品国产入口| 欧美精品一区二区三区蜜桃 | 久久综合狠狠综合| 久久综合色婷婷| 久久麻豆一区二区| 久久精品亚洲精品国产欧美kt∨| 久久久久国产精品厨房| 国产日韩亚洲欧美综合| 亚洲欧美日韩久久精品| 亚洲精品国产成人久久av盗摄| **性色生活片久久毛片| 午夜成人免费视频| 日产国产高清一区二区三区| 精品伊人久久久久7777人| 久久国产剧场电影| 成人毛片视频在线观看| 在线亚洲一区观看| 91麻豆精品91久久久久久清纯| 日韩一区二区三区免费看| 久久精品夜色噜噜亚洲aⅴ| 久久久精品tv| 中日韩av电影| 亚洲成人综合视频| 久久精品国产网站| 国产成人av一区二区三区在线| 亚洲综合自拍偷拍| 亚洲成人tv网| 秋霞av亚洲一区二区三| 麻豆精品国产91久久久久久| 视频一区视频二区在线观看| 黑人巨大精品欧美黑白配亚洲| 美女一区二区三区在线观看| 国产一区不卡在线| 99精品国产视频| 欧美图区在线视频| 日韩欧美亚洲国产精品字幕久久久| 精品欧美一区二区三区精品久久| 国产亚洲精久久久久久| 日韩片之四级片| 中文字幕日韩一区| 亚洲一区二区三区免费视频| 日本午夜精品一区二区三区电影| 国产一区二区在线电影| 色欲综合视频天天天| 在线免费不卡视频| 久久尤物电影视频在线观看| 综合欧美一区二区三区| 激情图片小说一区| 色婷婷综合久久久久中文一区二区| 日本乱人伦aⅴ精品| 欧美乱熟臀69xxxxxx| 国产精品麻豆一区二区| 亚洲妇女屁股眼交7| 国产一区二区在线视频| 欧洲国内综合视频| 久久久久久久久蜜桃| 午夜一区二区三区视频| 国产一区二区在线观看免费| 91福利在线观看| 久久色视频免费观看| 亚洲女人****多毛耸耸8| 免费在线观看一区二区三区| av中文字幕亚洲| 日韩精品在线一区二区| 三级不卡在线观看| 国产精品1区2区3区| 欧美人与z0zoxxxx视频| 中文字幕成人在线观看| 韩国女主播一区| 欧美人与禽zozo性伦| 国产精品女主播av| 日本网站在线观看一区二区三区| 国产不卡视频在线播放| 欧美tickling挠脚心丨vk| 亚洲成人你懂的| 色欧美乱欧美15图片| 国产精品第一页第二页第三页| 捆绑调教一区二区三区| 欧美日韩在线播放三区四区| 亚洲欧美日韩在线不卡| 国产精品一区二区久久精品爱涩 | 午夜精品一区二区三区电影天堂| eeuss鲁片一区二区三区 | 成人自拍视频在线| 4438x亚洲最大成人网| 香港成人在线视频| 色视频成人在线观看免| 亚洲人精品午夜| 国产精品一级在线| 国产精品福利av| 成人免费观看视频| 国产精品盗摄一区二区三区| 国产91精品在线观看| 亚洲国产高清在线观看视频| 国产一区二区三区不卡在线观看| 91精品国产91久久久久久最新毛片 | 亚洲男人天堂av| 不卡的电影网站| 亚洲免费观看高清| 欧美日韩精品电影| 青娱乐精品视频| 337p日本欧洲亚洲大胆色噜噜| 成人av资源下载| 亚洲视频图片小说| 欧美一区二区三区人| 青青青伊人色综合久久| 精品国产乱子伦一区| www.亚洲激情.com| 亚洲综合在线五月| 精品毛片乱码1区2区3区| 99re66热这里只有精品3直播| 亚洲一二三四久久| 日韩欧美一区二区久久婷婷| 国产精品资源在线观看| 1区2区3区国产精品| 在线观看一区二区视频| 国产一区二区三区四| 国产精品国产三级国产aⅴ中文| 一本一道波多野结衣一区二区 | 精品免费视频.| 成人18视频在线播放| 亚洲成人av电影在线| 久久麻豆一区二区| 91亚洲国产成人精品一区二区三| 亚洲第一成年网| 国产精品美女一区二区| 欧美日韩午夜在线| 国产成人免费xxxxxxxx| 九一久久久久久| 亚洲美女电影在线| 欧美va亚洲va国产综合| 99精品国产热久久91蜜凸| 男女性色大片免费观看一区二区 | 一本一本久久a久久精品综合麻豆 一本一道波多野结衣一区二区 | 亚洲精品成a人| 久久综合色播五月| 91精品国产黑色紧身裤美女| 97精品久久久久中文字幕| 精品一区二区三区免费毛片爱 | 欧美精品视频www在线观看| 色美美综合视频| 国产成人在线网站| 日韩成人午夜电影| 亚洲自拍偷拍九九九|