原創 淘系技術 淘系技術 7月12日

在網際網路公司,經常面臨一個“三高”問題: 高并發、高性能、高可用。
我們經常收到一些同學提問:我沒有高并發項目經驗,工作中沒有這樣的場景。但是面試的時候經常被問到高并發、性能調優方面的問題,有什麼辦法可以學習或者解決嗎?
這種時候,你需要有一個全局的技術視野,熟悉一些常用的系統優化方法論,以及學會一些關于系統設計的解答思路。
今天我們邀請了 3 名淘系技術工程師,給大家分享一些他們在高并發項目的學習實踐經驗&面試回答經驗,希望能夠對你有幫助。
01
淘系技術部-産品技術-昭明
“高并發系統是可遇不可求的,但其實是可以通過壓測來模拟的。”
現實中,哪怕是大公司,高并發系統也是可遇不可求的。不過,高并發其實是可以通過壓測來模拟的。
高并發的背後,核心是高可用和低延遲。是以我們其實是想有能力設計一個系統,在高并發通路的時候,系統依然可用,而且響應速度不會變慢。
想提升高并發系統的設計和開發能力,有2個方面:
- 系統的學習相關理論;
- 找一個目标系統,不斷想辦法去提升他的性能。
前者是後者的理論基礎。
如果想從事一個高并發系統開發的崗位,要學習的相關技術其實是很多的,這些技術核心就是解決高并發情況下如何保持系統的高可用和低延遲。
以Java工程師為例,網際網路程式員面試中經常會考察的内容包括:
架構設計
高可用與穩定性、事務一緻性、多副本一緻性、CAP理論。
相關技術
多線程(JUC/AQS/線程池)、RPC調用及架構(如Thrift)、NIO及NIO架構(如Netty)、高并發架構(如Disruptor) 、微服務架構(SpringBoot)、微服務治理(Spring Cloud)、資料庫相關技術(如:索引優化、分庫分表、讀寫分離)、分布式緩存(如redis)、消息中間件系統(如RabbitMQ)、容器技術(如docker)。
工具
系統性能檢視(top、uptime、vmstat、iostat)、壓測工具(如ab、locust、Jmeter、go)、線程分析(如jps、jstack)等。
當然,一開始,我們不可能逐一把這些技能全部掌握,我們可以從一個實際項目入手,不斷的把這些技術用上去,發現哪些知識不足,再去補充相關的知識。
“如何設計一個好的秒殺系統“,一定是網際網路大廠面試中最常問的一個問題。是以從設計一個秒殺系統開始實踐,是個不錯的選擇。
秒殺系統的特點:
- 瞬時并發量大
秒殺時會有大量使用者在同一時間進行搶購,瞬時并發通路量突增 10 倍,甚至 100 倍以上都有。
- 庫存量少
一般秒殺活動商品量很少,這就導緻了隻有極少量使用者能成功購買到。
- 業務簡單
流程比較簡單,一般都是下訂單、扣庫存、支付訂單。
設計秒殺系統的關鍵點
- 限流
由于活動庫存量一般都是很少,對應的隻有少部分使用者才能秒殺成功。是以我們需要限制大部分使用者流量,隻準少量使用者流量進入後端伺服器。
- 削峰
秒殺開始的那一瞬間,會有大量使用者沖擊進來,是以在開始時候會有一個瞬間流量峰值。如何把瞬間的流量峰值變得更平緩,是能否成功設計好秒殺系統的關鍵因素。實作流量削峰填谷,一般的采用緩存和 MQ 中間件來解決。
- 異步
秒殺其實可以當做高并發系統來處理,在這個時候,可以考慮從業務上做相容,将同步的業務,設計成異步處理的任務,提高網站的整體可用性。
- 緩存
秒殺系統的瓶頸主要展現在下訂單、扣減庫存流程中。在這些流程中主要用到 OLTP 的資料庫,類似 MySQL、Oracle。由于資料庫底層采用 B+ 樹的儲存結構,對應我們随機寫入與讀取的效率,相對較低。如果我們把部分業務邏輯遷移到記憶體的緩存或者 Redis 中,會極大的提高并發效率。
從0到1搭建一個秒殺系統,也并不容易,涉及到很多前端、後端、中間件的技術。這個跟其實是所有公司的工作常态,大部分時間也是在搭架子,真正做技術優化的時間并不多,經常是在業務量突增或者大促活動來臨時,集中搞一波性能優化。
是以,如果沒有實際的高并發項目可做,自己弄個秒殺系統自娛自樂也是不錯的。
搭建系統 -> 壓測 -> 發現問題 -> 學習知識 -> 優化系統,通過這樣的循環,相信你一定既能體驗到學習的樂趣,同時實力也大幅提升。
02
淘系技術部-行業與智能營運架構組-仲春
“在面試時被問到高并發經驗時不要慌,按照以下過程表達即可展現你的高并發設計能力:優化單請求耗時、提高單機并發能力、提高整體并發能力。”
個人認為,其實我們并不用去追求嚴格意義上的高并發經驗,因為很多時候都沒有這樣的機會給到你,對于高并發的處理經驗主要展現在日常的積累以及對自己的嚴格要求上。
為什麼總在說高并發?
在并發不高的場景下,不區分經驗是否豐富的任何人都能完成基本的業務開發,而且不會産生任何性能問題,下遊依賴、底層存儲依賴都不會對你的系統産生影響,但是在并發很高的時候,一切都變了,可能由于高并發環境時下遊抖了幾ms、db由于高寫入或者備庫讀壓力過大而導緻主備延遲了一下,你的系統或者業務都會産生故障。
如何積攢“經驗”?
對于這個問題,我總結3點可落地:
- 系統的設計優化
首先系統隻有無狀态的,才能不斷橫向擴充,才能支撐流量的變化,在業務層的高并發大多都需要不斷擴容來支援,但是擴容也不是最根本的方式,如果系統不做優化,一開始擴容大機率是有效的,到一定階段後就會發現情況開始惡化,因為底層的依賴競争開始激烈,失敗開始增多。優化的盡頭往往是對下遊依賴和底層資料層的優化,解決方案大多是常見的緩存分層、讀寫分離、分庫分表、異步化等等,但是引入這些技術方案時,會帶來一些副作用,接下來你需要解決和屏蔽這些副作用。
- 業務邏輯的優化
當你隻是在負責一個流量不大的系統時,是否就沒有高并發的機會了呢?其實不然,你需要不斷嚴格要求自己,讓業務跑的更快,例如:将單次請求響應耗時從100ms優化到20ms;單機能力從100qps提高到500qps,同時cpu消耗上漲不明顯;優化單次請求對緩存和db的放大系數降低,減少對緩存和db的壓力。在這個過程中你将積累大量的實戰經驗,完成業務開發很簡單,但是完成一個高效且具備高擴充性的業務開發卻是很難的,往前多想幾步,你會收獲很多。
- 壓測驗證
在業務體量沒有高并發的情況下,隻有自己人為創造流量來驗證(不過前提是你的系統支援全鍊路壓測,否則壓測資料會污染線上真實環境,如果暫時不支援,那麼恭喜你,你有機會做一次全鍊路壓測改造了),通過驗證在目标水位下的系統表現、機器表現,再繼續重複前面兩個過程,不斷疊代,直到無法扣細節,提高性能;
如何展示自己的高并發經驗?
隻要在日常研發過程中嚴以律己,做好各項設計和優化,不随意寫難易擴充和難易維護的代碼,面試的時候就能聊下去。在面試時被問到高并發經驗時不要慌,隻要按照以下過程表達即可展現你的高并發設計能力:
- 如何優化單請求耗時
這裡你會闡述如何設計和改造系統架構,有可能涉及到jvm的參數優化、各種依賴是如何選型,過程中你積累了哪些選型和優化的方式;
- 如何提高單機并發能力
這裡你會闡述在你的業務中,單機并發能力受限于哪些關鍵點,這裡主要的挑戰點是單機的限制條件以及單機資源的競争,你是如何設計克服的,過程中你積累了哪些設計原則;
- 如何提高整體并發能力
這裡你會闡述在叢集環境下最重要的亮點,就是如何處理跨機器的資源競争以及資料的一緻性問題,這裡将展現你整體業務架構設計能力;
綜上所述,面試時并不是要求你一定要有真實高并發的項目經驗,項目經驗隻是為了驗證你真的做過一些設計和優化,如果你能将高并發場景下的設計原則和可能遇到的問題場景和解法都表達清楚,那麼我相信面試官也是認可的。
03
淘系技術部-淘系基礎架構-羅集
“對于高并發系統設計,個人推薦可以自底向上的分成三個部分,首先是建立基礎知識體系,其次是熟悉業界解決方案,最後是分布式系統設計。”
首先高并發的系統也不是最初就設計出來的,一切解決方案都是來自于業務場景。
大多是針對特定時期内的問題與挑戰,一步一步演化出來的。即便是在有高并發場景的公司裡的研發同學,如果不是去參與解決這些問題,往往也不能直接獲得高并發的經驗積累。是以沒有場景的公司裡面的研發同學,大家的起點其實是差不多的,完全不用虛,關鍵還是在于掌握其中的核心科技。
對于高并發系統設計,個人推薦可以自底向上的分成三個部分,首先是建立基礎知識體系,其次是熟悉業界解決方案,最後是分布式系統設計。
知識體系的建立要更多的去關注底層,如算法、緩存、多線程、并發、JVM、OS、網絡、分布式理論等,這些東西相對穩定,在這些底層技術的基礎上的解決方案好像層出不窮,如各種緩存技術、各種消息隊列、各種資料庫。但是掌握了底層原理,再去看上層的解決方案就能有觸類旁通的效果。對于最後的分布式系統設計,就是針對具體業務場景去應用相應的技術,組裝成一套體系的方案。
對于知識的學習資料網上已經非常多,可以自行學習建立體系。自己公司沒有具體的場景,就去各大公司的技術部落格學習業界方案。業界方案的學習推薦更多的思考其中的原因(Why),這個才是系統設計的核心。
比如一個環節拿掉會對系統産生什麼樣的影響?換成另外一個技術會有什麼不同?下面主要講一下面試中對于系統設計的解答思路。
第一步,提取設計目标
分布式系統設計中一定要明确自己的設計目标,比如系統的延遲和吞吐量,有時候是不可兼得的,會直接影響到具體的技術選型。面試中自己沒有實際的項目不要緊,可以針對某個假設的業務場景提取出系統設計的假設,多與面試官溝通交流,說明清楚自己是基于怎樣的需求來做這個設計。
第二步,核心子產品設計
接下來就是對系統的模組化,需要哪幾個核心子產品,這個階段主要關注功能的滿足,比如核心的算法選擇,資料模型設計。
第三步,擴充設計
識别系統的瓶頸點,結合所需要達到的系統名額。合理的對系統分層,并選用常見的擴充技術,如:
- 負載均衡
- 水準擴充
- 資料分片
最後,高并發系統的設計是一個負責且系統的工程,目标絕不僅僅隻關注性能,實際上要同時關注高可用和擴充性。是以在實際方案的設計中,除了要考慮正常情況下性能名額是否能夠達成,還要考慮在各種異常情況下系統是否能處于可控的狀态,如不能因為一個異常情況就發生系統雪崩,另外網際網路業務都是處于高速疊代和發展的過程,要保證未來的場景有足夠的演進空間。
如上,我們在日常工作和面試經曆中并不一定能夠真實經曆高并發系統,但是我們依然有多種學習和實踐方式獲得類似經驗。如果能夠嘗試去學習和了解高并發場景下的設計原則,以及可能遇到的問題場景和解法,等真正遇到高并發項目的時候,效果也是事半功倍。
希望以上分享對大家有所幫助。一起加油~