你們都是怎麼確保系統不被突然的訪問流量壓垮的?

行長家的IT民工


確保系統的高可用,要做的事情非常多,比如使用 Redis 緩存數據庫的數據,降低數據庫的壓力,同時也要注意緩存穿透、雪崩、擊穿等問題;但要是說到“不要被突增的訪問量擊垮”,通常就會到我們常說的分佈式架構三板斧:限流、熔斷、降級。


01. 限流

限流理解起來很簡單,比如故宮每天只賣八萬張票,超過八萬的遊客,無法買票進入,因為如果超過八萬人,景點的工作人員可能就忙不過來,過於擁擠的景點也會影響遊客的體驗和心情,並且還會有安全隱患;只賣N張票,這就是一種限流的手段。

軟件架構中的限流也一樣,就是流量徒增的時候,只允許一部分流量進來,而多餘的那部分,就拒絕掉。

通常我們可以通過限流算法達到這樣的效果,比如計數器法、滑動窗口法、漏桶算法、令牌桶算法,每個算法的詳解之前的文章有介紹過,這裡就不在佔用篇幅了。上面的例子中,故宮每天只賣八萬張票,有點兒類似於令牌桶算法,票就相當於令牌,只有拿到令牌的請求,才能訪問到服務。

另外限流可以針對不同的系統或業務流程限流,比如核心系統 A 要做限流,B 系統調用 A 系統很重要,C 系統調用 A 系統相對來說不是那麼重要,所以當 A 系統有些扛不住的時候,可以限制 C 系統的調用次數,保證 B 系統的穩定運行。


02. 熔斷

現實生活中,保險絲的作用就是熔斷,可以在發生短路的時候自動跳閘,保護家電。

在我們大部分應用場景中,A 系統調 B 系統接口,B 系統再調 C 系統接口這樣的場景非常多,這就是調用鏈路:A->B->C->D;每個系統的承載上限肯定是不一樣的,比如流量徒增,D 系統達到承載上限了,D 系統的接口響應非常慢,這樣可能會導致 A/B/C 調用它時出現超時等待的情況;如果進一步惡化,會導致鏈路雪崩,從一個服務的故障,變成了多個系統的故障。

這時候熔斷就排上用場了,如果短時間內有大量的請求超時,那麼就意味著這個系統出現了故障,那麼就沒有必要再去訪問這個服務了,這時候就要使用熔斷,斷開這條鏈路。

熔斷器還可以自動診斷下游服務的狀態,如果服務恢復的話,那麼再慢慢釋放請求,直到故障發生前的狀態。


03. 降級

服務降級既可以通過代碼自動判斷,比如上文的服務限流中說到,當流量徒增,可以限制不重要的系統或服務的訪問量,這裡的誰重要誰不重要,就算是服務級別的區分,當訪問量徒增,哪些系統是可以自動降級的。

服務降級也可以人工根據突發情況切換;比如在某些服務節點的時候(例如雙 11, 618),為了保證購物和支付的正常運行,會禁用一些不重要的服務;甚至在購物和支付兩者之間,購物更重要,所以可以提前預付或者延遲支付。

總之,限流、熔點和降級都是在流量徒增、過大時,保證系統穩定的手段。

我將持續分享Java開發、架構設計、程序員職業發展等方面的見解,希望能得到你的關注。


會點代碼的大叔


在複雜的生產環境下可能部署著成千上萬的服務實例,當流量持續不斷地湧入,服務之間相互調用頻率陡增時,會產生系統負載過高、網絡延遲,硬件負荷過載等一系列問題,從而導致某些服務不可用。如果不進行相應的流量控制,可能會導致級聯故障,並影響到服務的可用性,因此如何對高流量請求進行合理控制,成為保障服務穩定性的關鍵。限流可通過對某一時間窗口內的請求數進行限制,保持系統的可用性和穩定性,防止因流量暴增而導致的系統運行緩慢或宕機。

流量激增,常見策略是什麼?

緩存為客戶端(瀏覽器,app等),代理服務,後臺服務,數據庫等設定緩存。對頻繁讀的數據儘可能的從前端到後端進行合理的數據緩存。類型的緩存功能描述及常用技術舉例:

降級系統中的非核心服務,如果遇到流量過大的情況,那麼就把這個服務降級掉。例如:當獲取數據列表,然後對數據進行排序展示,如果在大流量下,這個排序就可以降級掉。

傳輸數據傳輸過程中可以對數據進行壓縮處理,從而減少網絡帶寬。

規則請求訪問過程中可以通過防火牆,請求代理服務,前後端業務邏輯設定訪問規則進行安全控制,過濾掉非法數據請求。如訪問時段,請求url,IP黑白名單等規則設定。

限流限流控制在網絡傳輸中是一個常用的概念,它用於調整網絡包的發送數據。然而,從系統穩定性角度考慮,在處理請求的速度上,也有非常多的講究。任意時間到來的請求往往是隨機不可控的,而系統的處理能力是有限的。我們需要根據系統的處理能力對流量進行控制。在一定時間內把請求限制在一定範圍內,保證系統不被沖垮,同時儘可能提升系統的吞吐量。這種限流方式的控制如同人們生活中經常遇到的,早晚高峰地鐵站通過排大長龍進站乘車達到限流的目的,為了保證地鐵站不會因為突然的客流高峰而被沖垮,而中斷正常的運營。

有些時候,緩存、降級、壓縮等只能解決系統運營中流量的一部分問題,但是不能解決核心的應用服務之間流量控制的問題。例如,即將到來第十個天貓雙十一狂歡節,用戶的購買,支付等行為,是涉及到大量寫操作,且是核心鏈路服務。類似這樣的核心操作服務是無法通過降級來達到提高系統服務運營穩定性的,這個時候,限流就比較重要了。

常見的限流算法

計數器算法計數器算法指在一段時間內,進行計數,與閥值進行比較,如果超過了閥值則進行限流操作,到了時間臨界點,將計數器清零進行重新基數,即單位時間段內可訪問請求的次數進行控制。計數器算法是一種比直觀簡單的限流算法,常用於應用服務對外提供的接口層面。

由於計數器算法存在時間臨界點缺陷,因此在時間臨界點左右的極短時間段內容易遭到攻擊。比如設定每分鐘最多可以請求100次某個接口,如12:00:00-12:00:59時間段內沒有數據請求,而12:00:59-12:01:00時間段內突然併發100次請求,而緊接著跨入下一個計數週期,計數器清零,在12:01:00-12:01:01內又有100次請求。那麼也就是說在時間臨界點左右可能同時有2倍的閥進行請求,從而造成後臺處理請求過載的情況,導致系統運營能力不足,甚至導致系統崩潰。

滑動窗口算法滑動窗口算法是指把固定時間片進行劃分,並且隨著時間的流逝進行移動,通過這種方式可以巧妙的避開計數器的臨界點的問題。也就是說這些固定數量的可以移動的格子,將會進行計數判斷閥值,因此格子的數量影響著滑動窗口算法的精度。

滑動窗口算法可以有效的規避計數器算法中時間臨界點的問題,但是仍然存在時間片段的概念。同時滑動窗口算法計數運算也相對計數器算法比較耗時。時間片段越精確,流量控制越精密,從而導致計算耗時越長。

漏桶算法漏桶算法設計思路比較直觀簡單,即水(請求)以不確定的速率先進入到漏桶裡,然後漏桶以一定的速度出水(接口有響應速率),當水流入速度過大會直接溢出(訪問頻率超過接口響應速率),然後就拒絕請求,可以看出漏桶算法能強行限制數據的傳輸速率。因此漏桶算法在這方面比滑動窗口而言,更加先進。

漏桶算法需要設定兩個參數,一個是桶的容量大小用,用來決定最多可以存放多少水(請求),一個是水桶漏的大小,即出水速率,即出水速率決定單位時間向服務器請求的平均次數。因此漏桶算法存在如下兩個問題:

漏桶的漏出速率是固定的參數,所以即使網絡中不存在資源衝突(沒有發生擁塞),漏桶算法也不能使流突發到端口速率提高。因此漏桶算法對於存在突發特性的流量來說缺乏效率。漏桶的漏出速率是固定的參數同時水桶容量大小限制,那麼意味著如果瞬時流量增大且超過水桶水桶容量的話,將有部分請求被丟棄掉(也就是所謂的溢出)。

令牌桶算法令牌桶算法是和水桶算法效果一樣但方向相反的算法。隨著時間流逝,系統會按恆定時間間隔往桶裡加入制定數量的水,如每100毫秒往桶裡加入1000毫升的水,如果桶已經滿了就不再加了(說明:令牌桶算法和漏桶算法相反,漏桶算法是按照客戶請求的數量往漏桶中加水的,而令牌桶算法是服務器端控制往桶裡加水的)。當有新請求來臨時,會各自從桶裡拿走一個令牌,如果沒有令牌可拿了就阻塞或者拒絕服務。

令牌桶算法的優點如下:

服務器端可以根據實際服務性能和時間段改變改變生成令牌的速度和水桶的容量。 一旦需要提高速率,則按需提高放入桶中的令牌的速率。生成令牌的速度是恆定的,而請求去拿令牌是沒有速度限制的。這意味著當面對瞬時大流量,該算法可以在短時間內請求拿到大量令牌,而且拿令牌的過程並不是消耗很大的事情。算法總計:以上四種算法均可以達到流量控制的目的,不論是對於令牌桶拿不到令牌被拒絕,還是漏桶的水滿了溢出,都是為了保證大部分流量的正常使用,而犧牲掉了少部分流量,這是符合設計規範和運營需求且合理的算法。如因極少部分流量需要保證可能導致系統達到極限而掛掉,則得不償失。

Sentinel限流產品介紹

Sentinel 譯為哨兵。這個命名形象的詮釋了Sentinel在分佈式系統中的工作角色和重要性。Sentinel 是面向分佈式服務架構的輕量級流量控制產品,主要以流量為切入點,從流量控制、熔斷降級、系統負載保護、監控管理等多個維度來幫助保護服務的穩定性。,這個命名形象的詮釋了Sentinel在分佈式系統中的工作角色和重要性。Sentinel作為一個調配器,可以根據需要把隨機的請求調整成合適的形狀,如下圖所示:

Sentinel具有以下特徵:

· 豐富的應用場景:Sentinel承接了阿里巴巴近10 年的雙十一大促流量的核心場景,例如秒殺(即突發流量控制在系統容量可以承受的範圍)、消息削峰填谷、實時熔斷下游不可用應用等。

· 完備的實時監控:Sentinel同時提供實時的監控功能。可以在控制檯中看到接入應用的單臺機器秒級數據,甚至500 臺以下規模的集群的彙總運行情況。

· 廣泛的開源生態:Sentinel提供開箱即用的與其它開源框架/庫的整合模塊,例如與Spring Cloud、Dubbo、gRPC 的整合。只需要引入相應的依賴並進行簡單的配置即可快速地接入Sentinel。

· 完善的SPI 擴展點:Sentinel 提供簡單易用、完善的SPI 擴展點。可以通過實現擴展點,快速的定製邏輯。例如定製規則管理、適配數據源等。

Sentinel功能介紹

· 流量控制:同一個資源可以對應多條限流規則。FlowSlot 會對該資源的所有限流規則依次遍歷,直到有規則觸發限流或者所有規則遍歷完畢。流量控制方式有基於QPS/併發數的流量控制、基於調用關係的流量控制(根據調用方限流、根據關係的資源流量控制,根據調用鏈路入口限流等)。

· 熔斷降級:熔斷降級是指當資源處於不穩定的情況下,在接下來的時間窗口之內,對該資源的調用都自動熔斷。通常用平均響應時間和異常比例兩種方式來衡量資源是否處於穩定的狀態即。

· 熱點參數限流:熱點參數限流會統計傳入參數中的熱點參數,並根據配置的限流閾值與模式,對包含熱點參數的資源調用進行限流。熱點參數限流可以看做是一種特殊的流量控制,僅對包含熱點參數的資源調用生效。Sentinel 利用LRU 策略,結合底層的滑動窗口機制來實現熱點參數統計。LRU 策略可以統計單位時間內,最近最常訪問的熱點參數,而滑動窗口機制可以幫助統計每個參數的QPS。

· 系統負載保護:當系統負載高於某個閾值,就禁止或者減少流量的進入;當系統負載開始好轉,則恢復流量的進入。

· 黑白名單控制:黑白名單根據資源的請求來源限制資源是否通過,若配置白名單則只有請求來源位於白名單內時才可通過;若配置黑名單則請求來源位於黑名單時不通過,其餘的請求通過。

· 實時監控:實時監控可根據系統提供的秒級日誌記錄實現包含單點監控,鏈路監控,簇點監控。

· 控制檯:Sentinel提供一個輕量級的控制檯,它提供機器發現、單機資源實時監控、集群資源彙總,以及規則管理的功能。

Sentinel 的開源生態

Sentinel提供對Web Servlet,Dubbo,Spring Boot ,Spring Cloud,gRPC,Apache RocketMQ,Redis等集成支持。

總結

在項目設計開發和運營中難免會遇到大流量訪問的情況,除了參考當應對大流量常用策略優化之外,還應考慮到應用服務本身流量的控制和監控。比如微服務架構模式下可針對性的某些特定服務之間進行流量控制和監控,實時瞭解系統運營和穩定情況,動態增減服務節點,從而提高系統的穩定性和健壯性,進而為用戶提供更高質量的服務。


御用一品刀


兩個方向來思考和回答這個問題:

第一點是努力提升整體系統的性能,

首先需要做壓測,分析系統當前的容量和瓶頸,對照對業務場景容量的評估,評估是否要提前做擴容。

性能瓶頸的問題,那就是更細的活了,需要從系統、架構、接口、代碼層面來優化。

第二點就是當前系統總有性能的上限,遇到流量異常突增,那該怎麼辦?

限流,思路是確保能處理的流量可以得到處理,超限的流量拒絕,典型場景是秒殺。

降級,思路是保證業務的關鍵流程,捨棄分支流程。實際上降級主要用在服務不穩定情況下,當然高併發流量是導致系統不穩定的一個重要因素。

另外,需要對系統的各個環節做好監控,以便及時發現異常,及時處理。

把系統部署在彈性雲上,則可以進行動態的擴容和縮容。

最後,並不是說上述的一個策略就能解決所有問題,保證系統的高可用是一個很複雜的工作,需要方方面面的努力。


SunnnyChan


在系統的設計之初就要想到這個問題,建議使用微服務架構,對流量壓力大的微服務,多配置服務器,沒有什麼流量壓力是多配置一臺服務器不能解決的,如果不夠,那就多配10臺,再不夠,就100臺,簡單粗暴而有效,我就不信那個邪。代碼優化得再好,不如增加一個實例。


內求於心順天道


kafka消息中間件瞭解一下,削峰限流


我取了8遍名字


一般的業務服務系統大體上就是通過網絡遠程對DB進行讀寫。如果流量突然飆大,總有一個資源會遇到瓶頸。按照經驗大概出問題地方是DB磁盤io、CPU、帶寬、連接數、內存其中的一個或幾個。不同的業務,不同的系統設計,出問題的地方會有所不同。如果流量增大數倍,勢必某個資源會在瞬間被榨乾,然後所有的服務都會“開小差”,引起用戶的抱怨。而解決問題的關鍵,是在問題發生時,儘量減少出問題的資源被訪問。

對於這個問題,我這裡給出兩個回答,一個是應付面試的,一個面向實際的。大家各取所需。

面試中怎麼回答

面試官其實就想聽到幾個術語的解釋而已——緩存、服務降級、限流。

緩存,就是用內存來頂替一部分DB的查詢+數據的處理。這應該是所有業務開發人員的必修課。業務上大致可以把緩存分為三類:瀏覽器緩存(HTTP Cache-Control Header),CDN和服務器業務緩存。而業務緩存根據實現的結構可以分多個層級,可以用in-memory cache (如Guava Cache),或者是分佈式共享Cache(如Redis)。在設計緩存一致性更新模式時,無非就是Cache Aside、Read/Write Through和Write Behind這三大種模式。有些超級NB的緩存系統自帶Cluster加持(比如Ehcache即可單機用,也可以組集群)。限於本文主題,具體的緩存設計不贅述。

留意下這裡說的緩存僅僅是利用了內存訪問比磁盤訪問快得多的特性(大概可以理解為2~3個數量級),並不會讓用戶感知到數據一致性哪裡不對勁(與下面的降級不同)。

服務降級,是指通過降低服務質量的方法,達到節省資源的目的。簡單來說就是棄車保帥。比如你的服務有ABC,平時消耗差不多的資源。突發事件時,A的請求量極大的增高了,B和C沒有變化。那麼可以比如減少或者暫停B和C的服務,省出資源給A用。

再比如,一個熱點新聞的業務,有新聞內容,有評論,有點贊數等等。一旦新聞熱點了,就可以把所有這些內容“靜態化”,不必再查DB。這時雖然評論,點讚的數暫時就不準了,但是主要的服務——內容,還是讓用戶可以看到。這就足夠了。

可以看到,降級的具體的方案,要結合業務和系統實現來綜合設計,並沒有定法。

降級很多時候也會用到緩存。只不過這時候使用緩存的方法就可能會以犧牲數據一致性為代價——內存裡的數據和DB不一樣,就不一樣吧,業務上可接受,並且這段熱點時間段過去了,能夠恢復為一致就可以。

限流,即限制用戶的請求流量。具體的做法有計數器、滑動窗口、滴漏、服務token、請求隊列化等辦法。這些方法的詳細解釋,在這裡都說得比較清楚,所以我就不重複了。只是值得注意的是,現在很多生產級別的服務都是多節點分佈式架構。很多單機上容易做的算法和控制邏輯到了分佈式下就會帶來一些實現上的麻煩。這又涉及到了分佈式一致性、CAP的權衡等等問題。

怎麼樣,這些足夠你在10分鐘內和麵試官白話一番了吧。下面我們說說真的。

真實世界的流量問題

凡事總有第一次

如果你的系統是第一次遇到流量突然增大的問題,而之前又沒有任何準備的話,那麼此問題無解。這一般出現在初創公司。你只能眼睜睜的和你的同事大眼瞪小眼,彼此唉聲嘆氣,並祈禱這段時間趕緊過去,同時老闆最好不要得到系統掛掉的消息(雖然幾乎不可能)。


這事沒發生,沒發生……

有人說,流量來了,我馬上去買幾臺雲服務器,配合使用來自於NB公司的服務框架的配置調整,然後nginx reload一把,不就手到擒來了?問題在於,儘管對於無狀態的服務可以比較簡單的擴容,作為有狀態的DB是無法隨意擴容的——而DB在流量突然增高的情況下往往就是系統瓶頸。退一步說,就算一開始是無狀態的應用服務器的CPU是瓶頸,然後馬上擴容應用服務器,那麼這個瓶頸也會最終壓到DB上。DB的擴容方案需要另花時間長篇大論一番,這裡就不再深入講了。

另外,即便是在新機器上部署業務服務器,在沒有準備的情況下十之八九也會出問題。why?對於一個乾淨服務器:

  • 你得裝環境鏡像吧。萬一著急OS版本號沒看清,和其他業務服務器不一樣,從而使得程序跑起來不一樣怎麼辦?內核bug並不少見。萬一現有的主機被調整了一些系統參數(比如tcp一類的),而新的環境忘了怎麼辦?
  • 雲服務器的實際環境你是看不見的。你新上了一批,怎麼就敢拍胸脯說它們和之前的機器——那個文詞怎麼說來著——同構?
  • 你得裝最新的應用包吧。之前得裝業務服務本身(比如一個war包),你能確保在混亂的情況下這裡給的war就是能用的war?現在有了docker相對好一些,但是docker是可能有bug的,尤其是早期版本(我遇到過……),比如在一個地方起得來,換一個地方就起不來,或者連不上網。你敢打包票沒問題?
  • 有了應用得配置吧,不管是環境變量還是properties文件,外部依賴、DB鏈接、各種秘鑰證書、各種只有開發才知道什麼意思的配置可能多達幾十個,全都得弄對。你敢說你能一次搞對?

以上這些事情,有任何一步出錯,造成的問題都可能比流量本身更嚴重。我相信,如果這個流量問題是第一次,那麼幾乎可以肯定,項目組應該沒準備過任何的服務治理的方案,更不要說演練。

那些N年前雲計算吹噓的彈性如何如何,能快速部署如何如何的slogan,在沒有業務和系統設計的支持下,只是噱頭罷了,不要太當真。

以上問題,如果你的公司可以輕易的做到,就說明運維已經做的極度可靠和強大。運維可以達到這種程度,是經過不懈的努力和大量的資源付出才能得到的。

所以,關鍵的問題是,要對高流量的到來有所準備。要提前設計方案,無論是降級限流還是別的什麼歪招。要設計、實現、測試、生產實機演習,只有這樣才能保證到了關鍵的時候才能用得起來。而這些事情將會花費技術團隊大量的資源。

總是預先準備

當設計一個業務時,產品設計和研發團隊應該找個時間,除了討論產品本身怎麼實現之外,還應該關心一下如下幾點的實施:

流量估算。到底大概有多少人可能會用呢?對於大公司,都有長時間運營的經驗,可以參照之前的產品/活動給出一個量化的估算結果。但是小公司往往就只能拍腦袋。但即便是拍腦袋也比沒有強,可以作為設計容量的依據。這下你明白為啥有些公司面試時會出“你覺得本城市有多少個輛汽車”這樣的題目了吧。

作為一個經驗,可以把設計流量*3作為系統壓力的下限——即,實現完了要壓測,壓測得到的結果要達到設計流量 * 3。當然如果是你的話,要 * 4, * 5都可以,關鍵是要給系統留些緩衝。一旦發生了什麼,不至於掛的太慘。此時,一般會得到一個帶緩存的業務服務系統。考慮到緩存高於後臺服務2~3個數量級的性能優勢,多撐幾倍流量一般不成問題。

降級方案。降級總得是用戶可以買賬的方式才行,不能瞎降。能降級成什麼樣,顯示成什麼樣子,都得預先設計好。UI上有的要配圖,有的要出警告語提示。而作為後臺服務器,需要有對應的實時開關,一旦設置,立刻進入降級方案。

但是,如果核心服務就是熱點本身,就沒得降級,那就尷尬了…… 比如下單就是下單,不能下一半,不能砍掉支付,不能隨機性有的能買有的不能買。這時就得靠限流。

限流方案。上面提到了種種限流算法——計數器、滑動窗口、滴漏、服務token、請求隊列化,等辦法技術在更加傳統的模版式頁面的網站更容易做——整個界面是由一個GET請求在後臺通過模版產生的。所以只要在這個請求處理過程中做限流控制即可。

但是在SPA或者移動端App時,一個界面可能是由數個或者數十個Ajax接口分批獲得。每個請求都做限流可能會得到隨機的半殘的界面——有幾個接口沒限制,有幾個被限制了。此時做限流還得考慮前後端架構設計。一般來講,每個主要界面都應該有個主控接口來實現限流(比如產品詳情接口)——即,一旦該接口說限流了,後續的前端代碼就得配合按照預先的設計顯示限流後的界面。同時會影響關鍵資源的接口在後端要再做一道限流——畢竟你不知道有沒有人繞開前端直接壓接口使壞不是。嗯,搶票就是這麼來的。

提前安排開發和演練排期。如果一切安排妥當,就可以做作演習了。你可以找個沒人用你服務的時間點(大半夜?)使用流量replay壓一下你的真實生產環境,看看真的發生了流量增高的問題,系統是否足夠健壯能夠應對,之前設計的種種方案是不是可以達到設計的需要。根據墨菲定律,可能會發生的事情一定會發生,不經演練的系統上線到了出問題的時候100%會讓你大開眼界。

然而,高能預警,做演練時:千萬千萬不要產生像你的模擬流量代替用戶下了一單並且扣款的事情……。

為啥技術方案難落地

講真,相關的工具開發和規範的制定其實並不難。大道理就那麼幾條。難的是讓高層意識到這個事情有多麼的重要,如果不做的話會帶來多麼巨大的代價。這是因為一個公司的高層可能是產品出身、營銷出身、供應出身,可以是個徹底的技術外行。讓他們理解技術的重要性,難度差不多就相當於讓孃親學會怎麼把手機裡的視頻投屏到電視。此外,技術團隊的主要目標往往是實現公司業務需求。在劈天蓋地的業務需求的夾縫中找到資源來優化技術基礎設施相當的苦難。畢竟公司活下去才是第一位的。

如果你成功的把你的頭頭勸服,並且為此申請了一大筆資金購買機器、招NB的人來做相關的基礎設施,而又不耽誤業務的話,你就是三樓樓長——呀不對,是CTO的好苗子。


你就是三樓樓長

當然,如果你說你在BAT,FLAG這樣的公司,那請自動忽略本條目。

也許是個業務問題

也許解決了技術問題還遠遠不夠。比如電商這個業務,可能業務上會預計有多少流量,但是到底備多少貨呢?多了費庫存,少了用戶罵。2017年雙十一就很明顯。淘寶上在雙十一的前一週網站的各大熱門產品都要“預約”。用戶預約了能拿到更多一點折扣,而對於商家,也大致瞭解了要備貨的數量。雙贏。

對於我做的業務——財富管理業務,買入信號是個很關鍵的觸發點。我們一旦偵測到了價格合適,就可以分期分批給用戶發通知,提示他們機會難得,該買啦。這樣用戶得到了方便(提示就買,不用自己刷刷刷),而我們可以大致控制進入系統的用戶數量不至於過多。雙贏。

最後,勞請客服支持的同學提前準備好小禮品,以備不時之需?。


我們的不時之需

相關問題

這裡稍微說一下高流量問題帶來的一些相關的問題。這裡僅僅是簡單列舉,具體內容之後找時間細細說。

  • 雪崩效應——如果用戶看到“服務開小差”,他的第一反應一定是再刷一次;如果是微服務架構,服務與服務之間可能會有自動重試機制。而這些,會讓已經半死的系統死的更透徹。對此類問題,一般使用斷路器的方案,簡單來說就是,如果一個服務已經證明快掛了,就別再調用了,直接fallback。等一會再試。nginx裡的upstream控制有max_fails和fail_timeout處理這個問題。Hystrix也實現了該機制。但斷路了不等於讓用戶看到404頁面罵娘,一定要結合業務+產品設計來實現斷路方案。
  • 無效的服務響應——在高壓下,可以簡單將等待處理的服務看作是在排隊,隊首的請求被處理。但被最終“見”到處理邏輯的請求從隊尾排到隊首時可能已經過了比較長的時間,而客戶端那邊可能早就超時了。所以業務服務處理了也是白處理。這時如果隊列系統做得好,比如要處理前先猜一次是不是處理完了會超時,如果是就忽略扔掉。可以減少這種問題的發生幾率。這也算是一種服務降級。
  • 大量的TIME_WAIT——如果業務服務器的壓力造成服務端大量主動關閉連接,就會產生大量的TIME_WAIT狀態的TCP鏈接。這些鏈接會在數分鐘內像殭屍一樣堆在那裡,榨乾所有的連接數。這種問題尤其以自研業務服務框架容易出現。
  • 一致性——為了服務降級,可能會把用戶請求放內存裡緩一緩,再批量進DB。那麼一旦系統出現故障,就意味著比如下單數據不一致,支付狀態不一致等問題。有時,這些問題在業務上極大的影響用戶的使用體驗。當系統降級時,儘量保證,要不就告訴用戶現在不能給你服務,要服務了結果就明確。對於交易這種業務,事前打臉還是比事後扯皮要好一些。兩害取其輕。
  • 系統可能會臨時stop the world——對於java這樣的系統,會因為GC而暫時卡那麼一下;對於mongoDB,可能因為要底層flush數據到磁盤,也會卡那麼一下;平時寫的什麼正則表達式處理一類的邏輯,在高峰期也可能會卡那麼一下…… 平時一般沒事,但是趕上高峰時,這些問題一旦出現就有可能成為壓垮駱駝的最後一根稻草。因此平時還是多多壓測和演習,心裡踏實。

我一時大抵只想到這些。


一車三人行


使用緩存系統,例如memcache,或者 varnish,優化系統架構,負載均衡,綜合運用吧。


tengyue


不請自來,用錢。


分享到:


相關文章: