天天看點

以淘寶網為例,解析大型Java項目架構演進

以淘寶網為例,簡單了解一下大型電商的服務端架構是怎樣的。如圖所示

最上面的就是安全體系系統,中間的就是業務營運系統,包含各個不同的業務服務,下面是一些共享服務,然後還有一些中間件,其中 ECS 就是雲伺服器,MQS 是隊列服務,OCS 是緩存等等,右側是一些支撐體系服務。

以淘寶網為例,解析大型Java項目架構演進

除圖中所示之外還包含一些我們看不到的,比如高可用的展現。淘寶目前已經實作多機房容災和異地機房單元化部署,為淘寶的業務也提供了穩定、高效和易于維護的基礎架構支撐。

這是一個含金量非常高的架構,也是一個非常複雜而龐大的架構,當然這個架構不是一天兩天演進成這樣的,也不是一開始就設計并開發成這樣的,對于初創公司而言,很難在初期就預估到未來流量千倍、萬倍的網站架構會是怎樣的狀況,同時如果初期就設計成千萬級并發的流量架構,也很難去支撐這個成本。

是以一個大型服務系統,都是從小一步一步走過來的,在每個階段找到對應該階段網站架構所面臨的問題,然後不斷解決這些問題,在這個過程中,整個架構會一直演進,同時内含的代碼也就會演進,大到架構、小到代碼都是在不斷演進和優化的。是以說高大上的項目技術架構和開發設計實作不是一蹴而就的,這是所謂的萬丈高樓平地起。

以淘寶網為例,解析大型Java項目架構演進

從一個小網站說起,一般來說初始一台伺服器就夠了,檔案伺服器、資料庫以及應用都部署在一台機器上。也就是俗稱的 allinone 架構。

以淘寶網為例,解析大型Java項目架構演進

随着網站使用者逐漸增多,通路量越來越大,硬碟、cpu、記憶體等開始吃緊,一台伺服器難以支撐。看一下演進過程,我們将資料服務和應用服務進行分離,給應用伺服器配置更好的 cpu、記憶體等等,而給資料伺服器配置更好、更快的大的硬碟,如圖所示用了三台伺服器進行部署,能提高一定的性能和可用性。

以淘寶網為例,解析大型Java項目架構演進

随着通路的并發越來越高,為了降低接口的通路時間提高服務性能,繼續對架構進行演進。

我們發現有很多業務資料不需要每次都從資料庫中擷取,于是我們使用了緩存,因為 80% 的業務通路都集中在 20% 的資料上 (二八原則),如果能将這部分資料緩存下來,性能就能提高很多,緩存又分兩種,一種是 Application 中的本地緩存,還有遠端緩存,遠端緩存又分為遠端的單機式緩存和分布式緩存 (圖所示的是分布式緩存叢集)。

我們需要思考幾點,具有哪種業務特點的資料使用緩存,具有哪種業務特點的資料使用本地緩存,具有哪種業務特點的資料使用遠端緩存。分布式緩存在擴容時會遇上什麼問題,如何解決,分布式緩存的算法都有哪幾種,都有什麼優缺點。這些問題都是我們在使用這個架構時需要思考并解決的問題。

以淘寶網為例,解析大型Java項目架構演進

這個時候随着通路的 qps 不斷提高,假設我們使用的 Application Server 是 tomcat,那麼 tomcat 伺服器的處理能力就會成為一個瓶頸,雖然我們也可以通過購買更強大的硬體但總會有上限,并且這個成本到後期是呈指數級的增長。

這時候就可以對伺服器做一個叢集 (cluster),然後添加負載均衡排程器 (LoadBalancer),伺服器叢集後我們就可以橫向擴充我們的伺服器了,解決了伺服器處理能力的瓶頸。

此時我們又需要思考幾個問題, 負載均衡的排程政策都有哪些,各有什麼優缺點,各适合什麼場景,比如輪詢、權重、位址散列,位址散列又分為原 IP 位址散列、目标 IP 位址散列、最小連接配接、權重最小連接配接等等。

以淘寶網為例,解析大型Java項目架構演進

伺服器叢集後,假設我們登陸了 A 伺服器,session 資訊存放在 A 伺服器上了,如果我們的負載均衡政策是輪詢或者最小連接配接等,下次是有可能通路到 B 伺服器,這時候存儲在 A 伺服器上的 session 資訊我們在 B 伺服器是讀取不到的,是以我們需要解決 session 管理的問題。

我們使用 session sticky這種方式來解決這個問題,它的處理規則是對于同一個連接配接中的資料包,負載均衡會将其進行 NAT 轉換後,轉發至後端固定的伺服器進行處理,這種方案解決了 session 共享的問題。

如圖所示用戶端 1 通過負載均衡會固定轉發到伺服器 1 中。缺點是第一假設有一台伺服器重新開機了,那麼該伺服器的 session 将全部消失,第二是我們的負載均衡伺服器成了一種有狀态的伺服器,要實作容災會有麻煩。

以淘寶網為例,解析大型Java項目架構演進

session 複制,即當 browser1 經過負載均衡伺服器把 session 存到 application1 中,會同時把 session 複制到 application2 中,是以多台伺服器都儲存着相同的 session 資訊。

缺點是應用伺服器的帶寬問題,伺服器之間要不斷同步 session 資訊,當大量使用者線上時,伺服器占用記憶體會過多,不适合大規則叢集,适合機器不多情況。

以淘寶網為例,解析大型Java項目架構演進

基于 cookie,也就是說我們每次都用攜帶 session 資訊的 cookie 去通路應用伺服器。缺點是 cookie 的長度是有限制的,cookie 儲存在浏覽器上安全性也是一個問題。

以淘寶網為例,解析大型Java項目架構演進

把 session 做成了一個 session 伺服器,比如可以使用 redis 實作。這樣每個使用者通路到應用伺服器,其 session 資訊最終都存到 session server 中,應用伺服器也是從 session server 中去擷取 session。

要考慮以下幾個問題,在目前架構中 session server 是一個單點的,如何解決單點,保證它的可用性,當然也可以将 session server 做成一個叢集,這種方式适用于 session 數量及 web 伺服器數量大的情況,同時改成這種架構後,在寫應用時,也要調整存儲 session 的業務邏輯。

以淘寶網為例,解析大型Java項目架構演進

在解決了伺服器橫向擴充之後,繼續看資料庫,資料庫的讀與寫操作都需要經過資料庫,當使用者量達到一定量時,資料庫性能又成為了一個瓶頸,我們繼續演進。

我們可以使用資料庫的讀寫分離,同時應用要接入多資料源。通過統一的資料通路模型進行通路。資料庫的讀寫分離是将所有的寫操作引入到主庫中 (master),将讀操作引入到從庫中 (slave),此時應用程式也要做出相應的變化,我們實作了一個資料通路子產品 (data accessmodule),使上層寫代碼的人不知道讀寫分離的存在,這樣多資料源的讀寫對業務代碼就沒有侵入,這就是代碼層面的演變。

如何支援多資料源,如何封裝對業務沒有侵入,如何使用目前業務使用的 ORM 架構完成主從的讀寫分離,是否需要更換 ORM,各有什麼優缺點,如何取舍都是目前這個架構需要考慮的問題。

當通路量過大時候,也就是說資料庫的 IO 非常大,我們的資料庫讀寫分離又會遇到以下問題?

例如主庫和從庫複制有沒有延遲,如果我們将主庫和從庫分機房部署的話,跨機房傳輸同步資料更是一個問題。另外應用對資料源的路由問題,這些也是需要思考和解決的點。

以淘寶網為例,解析大型Java項目架構演進

我們繼續增加了 CDN和反向代理伺服器 (Reverseproxy server),使用 CDN可以很好的解決不同地區通路速度問題,反向代理則在伺服器機房中可以緩存使用者的資源。

以淘寶網為例,解析大型Java項目架構演進

這個時候我們的檔案伺服器又出現了瓶頸,我們将檔案伺服器改成了分布式檔案伺服器叢集,在使用分布式檔案系統時,需要考慮幾個問題,如何不影響部署線上上的應用通路,是否需要業務部門幫忙清洗資料,是否需要備份伺服器,是否需要重新做域名解析等等。

以淘寶網為例,解析大型Java項目架構演進

這個時候我們的資料庫又出現了瓶頸,我們選擇專庫專用的形式,進行資料的垂直拆分,相關的業務獨用自己的一個庫,我們解決了寫資料并發量大的問題。

當我們把這些表分成不同的庫,又會帶來一些新的問題。例如跨業務和跨庫的事務,可以使用分布式事務,或者去掉事務,或者不追求強事務。

随着通路量過大,資料量過大,某個業務的資料庫資料量和更新量已經達到了單個資料庫的瓶頸了,這個時候就需要進行資料庫的水準拆分,例如把 user 拆分成了 user1 和 user2,就是将同一個表的資料拆分到兩個資料庫當中,這個時候我們解決了單資料庫的瓶頸。

水準拆分時候又要注意哪些點,都有哪幾種水準拆分的方式。進行了水準拆分後,又會遇到幾個問題,第一 sql 路由的問題,假設有一個使用者,我們如何知道這個使用者資訊是存在了 user1 還是 user2 資料庫中,由于分庫了,我們的主鍵政策也會有所不同,同時會面臨分頁的問題,假設我們要查詢某月份已經下單的使用者明細,而這些使用者又分布在 user1 和 user2 庫中,我們背景營運管理系統對它進行展示的時候還要進行分頁。這些都是我們在使用這個架構時需要解決的問題。

以淘寶網為例,解析大型Java項目架構演進

在網站釋出并進行了大規模的推廣後,導緻我們應用伺服器的搜尋量又飙升,我們把應用伺服器的搜尋功能單獨抽取出來做了一個搜尋引擎,同時部分場景可以使用 NoSQL來提高性能。同時我們開發一個資料統一的通路子產品,同時連着資料庫叢集、搜尋引擎和 NoSQL,解決上層應用開發的資料源問題。

以淘寶網為例,解析大型Java項目架構演進

這裡隻是簡單舉例,并沒有依據什麼實際的業務場景。事實上各個服務的架構是要根據實際的業務特點進行優化和演進的,是以這個過程也不是完全相同的。當然這個架構也不是最終形态,還存在很多要提升的地方。

例如負載均衡伺服器目前是一個單點的,如果負載均衡伺服器通路不了,那麼後續的包括伺服器叢集等也就無法通路了。是以可以将負載均衡伺服器做成叢集,然後做一些主從的雙機熱備,同時做一個自動切換的解決方案。

在整個架構的演進過程中,其實還包含更多需要關注的内容,比如安全性、資料分析、監控、反作弊......

針對一些特定的場景例如交易、充值、流計算等使用消息隊列、任務排程......

整個架構繼續發展下去,做成 SOA 架構、服務化 (微服務)、多機房......

最後,我想說高大上的項目技術架構和開發設計實作絕不是一僦而就的。

END

以淘寶網為例,解析大型Java項目架構演進

繼續閱讀