應用架構對技術的追求要有所止境

JanessaJjq 7年前發布 | 33K 次閱讀 分布式系統 軟件架構

背景

說起架構,大多人想到的是技術語言、技術框架、SOA、微服務、中間件等,這些都是純粹的系統架構或基礎架構,它們基本不受業務影響,大多可以獨立于具體業務進行開發和發展,形成自己獨立的體系甚至標準化的技術產品。

但實際上大多情況下 技術是為業務服務 的,我們開發的更多的是應用系統或者稱之為業務系統,業務的不同特點決定了應用(業務)架構也必然有不同的特點。

而這些不同的特點單純靠技術肯定解決不了,應用架構設計的一條重要原則是 技術中立 ,所以更多時候我們要從應用的角度而不是技術的角度去考慮問題。

我做過電商核心交易相關系統,提起電商大家想到的自然是 PV、UV、高性能、高并發、高穩定、搶購秒殺、訂單、庫存、分布式事務 等。

這里的每一個點初聽起來都充滿著高深與神秘,以關心較多的秒殺為例(1000 萬人秒殺 100 塊 100g 的金條)我們來分析看看。

常規秒殺架構

常規架構如下

常規流量分布模型

展示層流量 > 應用層流量 > 服務層流量 > DB 層流量

超 NB 的系統流量分布模型如下

展示層流量 = 應用層流量 = 服務層流量 = DB 層流量

我們知道 DB 是系統最底層也是流量的最大瓶頸,從上面幾個圖可以看到,超 NB 的公司解決了 DB 瓶頸所有流量可以一路直到 DB 層,每一層都可以任意擴展,那么系統的壓力就可以輕松化解。

當然一些沒有經驗的系統也是這么做的,但 DB 層甚至其他層擴展做不好,所以系統經常掛。而實際上再 NB 的公司也不會這么去做,即使技術上能做到也沒有必要,因為 代價實在太大

所以我們要從 DB 層之前想辦法梯形 逐層進行流量過濾 ,也就成了上邊看到的常規流量分布模型,最好的結果就是到 DB 層流量只有實際的訂單數 100 (100 塊金條)。

秒殺流量過濾—常規思路

回到常規流量分布模型,以下是一個常用的秒殺系統流量過濾過程:

(點擊放大圖像)

如果純考慮技術極致,那簡單,把 DB 層的問題解決就好了,讓 DB 可以象應用層和服務層一樣隨時分布式擴展,可實際上 DB 做不到, DB 是最大的瓶頸 ,所以才有了 排隊系統預約系統

緩存是一定要用到的,但秒殺往往是瞬間的事,緩存的時效性導致緩存系統在這樣的大流量對 DB 的瞬間沖擊時幾乎沒有幫助。

如對秒殺商品的庫存更新使得大量的 udpate sql 直接到了 DB,DB 壓力非常大。我們嘗試了在 mysql 下先 select,有庫存時再 update,效果比較明顯,特別是秒殺單 sku 或少量 sku 的場景,因為 select 和 update 對 DB 的壓力大家懂的,有興趣的可以自行測試下看。

排隊系統是目前大多秒殺場景最常用的,本質是 異步處理放緩流量削平瞬間峰值 ,降低對后續服務層和 DB 層的流量沖擊。

預約系統的作用在于 提前預知流量 ,雖然預約量本身不可控,但秒殺前可以針對已知流量提前做好預案,讓 系統處于可控狀態

預約 + 排隊的方式已經可以滿足大多搶購秒殺場景的需要。

秒殺流量過濾—來點新思路

預約和排隊畢竟是 外掛系統 ,各層之間是否有必要做好自己的預案和防范呢,我們再上個圖逐層來看看想點辦法:

(點擊放大圖像)

DB 層

DB 層不能任意或隨時擴展,是最大的瓶頸和最后的底線,是絕對不能破的,一是 DB 并發連接不能超過最大連接數,二是 DB 壓力不能太大,所以流量必須在前端控制。

服務層

服務層雖然可以分布式擴展,但受限于 DB 連接,并不意味著可以無限擴展。如果是公共服務層不區分秒殺業務和普通業務,是不好做流量過濾的,因為會影響到普通業務的正常流量,這種情況下只能從應用層想辦法。

如果是單獨為秒殺流程服務,或者說流量來源能區分出秒殺業務或其他業務的,那還是有思路的,辦法總比困難多,如:

隨機數過濾

將一定百分比的用戶請求直接過濾返回給應用層包裝,以友好的方式返回提示給用戶。

預設閥值限流

設定單機在單位時間的處理最大閥值,如單機的實際處理能力 TPS 最大是 10000/ 秒,設定閥值為 20,當單機單位時間內(秒)的并發請求達到閥值時,后續請求直接返回給應用層,以友好的方式返回提示給用戶。

此時系統并不處理業務邏輯和進行 DB 操作,只是簡單地判斷和響應返回,所以單機的處理能力 20+X 是遠大于 10000/ 秒的。

注:上述兩種方法 并不是 串行或有依賴的,兩者都是一種可選的方法,它們的本質都是 流量過濾提升單機處理能力 保護系統以免被沖垮。

在保證一定用戶體驗(單機處理能力)的情況下將流量過濾最大化,如第 2 種方案中單機僅 20 的流量能到 DB 層,保證 DB 層絕對沒問題,如果服務層壓力依然大,可以繼續加分布式服務器和降低預設閥值。第 2 種方案實際上是第 1 種的升級版,更可控。

應用層

1、隨機數過濾,同上。

2、預設閥值限流,設定單機在單位時間的處理最大閥值,同上。

3、通過 Tomcat 最大連接數控制,超過最大連接數的請求 直接拒絕服務 ,但用戶體驗很不好,系統假死崩潰的感覺,盡量通過加分布式服務器的方式解決。(服務層一定要通過應用層控制不能超過最大連接數,展示層和應用層直接取決于用戶量,很難控制,可以使用預約系統讓流量可控)

展示層

隨機數過濾,將一定百分比的流量請求直接以友好的方式提示給用戶。

正常講展示層是 不應該過濾 的,請求都沒有到服務器 [攤手],但從業務角度看,搶購秒殺本身就是一個概率事件,并不是完全取決于先后順序 (有時后來的反而能搶到,這取決于分布式服務器處理、網絡、排隊系統的異步處理等)。

雖然對技術人來說欺騙用戶的感覺很不恥,但關鍵時刻偶爾抱一下佛腳也是一種辦法,總比系統被沖垮了好。

以上說的對幾個層的處理,并不是很好的方案或架構,只是想說明,一個小的思路或方案就可能解決不少問題,完全靠技術我們不一定能解決的了,而這些架構或方案與高深的技術本身并無太多直接關系。

對分布式事務的思考

再說一個例子。很多人非常關心怎么保證分布式事務,特別是異構系統和異構 DB,我也知道至少目前還沒有很好的技術手段來 徹底解決 這個問題,目前通用的方式就是回滾和補償。

當然很多人還少做了一招,即 數據對賬 ,但凡沒有事后進行回滾補償或數據對賬的架構方案,在分布式事務的最終數據一致性上都會有問題,畢竟這是異構的系統或 DB。如圖:

如果說秒殺還有些技術要求,那這里的分布式事務處理方案技術含量更少,只要 把細節做好 (回滾、補償、對賬),數據的準確性依舊 100%。

然而我們很多人把重點放在了分布式事務架構或技術方案,過于追求極致忽略或不削于這些容易的細節,系統反而問題不斷,無安寧之日。

某品牌手機為追求極致在一款高端手機上采用了特殊工藝的后蓋技術,結果因為技術原因導致該后蓋良品率低產量低,反而影響了核心產品手機的正常銷售量,得不償失。兩者有異曲同工之妙吧。

總結

應用架構很容易也很難,容易的在于 不需過多關注技術實現 ,難的在于 必須根據實際業務場景和業務需要及時間、成本、資源等給出當下最合適、一定不是最完美的架構方案 。

之前看過關于架構是設計出來的還是演進來的的討論,其實這個也簡單,在某個特定的階段或時間點,如系統初期,它一定是設計出來的。

但縱觀一個系統的架構歷程,或者說一定要在兩者間選擇一個的話,它一定是 演進而來 的。

所有的大型互聯網系統在初期一定不是設計成現在這個樣子的,都是伴隨著業務從小到大、從少到多、從簡單到復雜的過程演進而來, 架構的演進過程也見證了業務的發展歷程

技術無止境,但 應用架構(業務系統)對技術的追求要有所止境 ,當 DB 瓶頸解決不了時 換個思路 ,來個排隊系統和預約系統,技術難度就降低了很多;分布式事務解決不了,那就做好回滾、補償、對賬這些基礎工作。

馬步扎牢了,系統照樣可以健壯穩定高性能。多從應用架構的角度去思考解決方案,前面更有一片天!

作者介紹

張立剛,上海鮮備科技首席架構師,原 1 號店技術部架構總監,負責拆單、運費、庫存、訂單等電商核心交易系統,對電商核心業務、高并發、高性能等有深刻的理解和實踐。

感謝雨多田光對本文的審校。

 

來自:http://www.infoq.com/cn/articles/architecture-and-technic

 

 本文由用戶 JanessaJjq 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!