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

  • 若汐緣
    web

  • https://www.jianshu.com/p/796f488fd134redis

前言

以淘寶網爲例,簡單瞭解一下大型電商的服務端架構是怎樣的。如圖所示
最上面的就是安全體系系統,中間的就是業務運營系統,包含各個不一樣的業務服務,下面是一些共享服務,而後還有一些中間件,其中 ECS 就是雲服務器,MQS 是隊列服務,OCS 是緩存等等,右側是一些支撐體系服務。算法

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

這是一個含金量很是高的架構,也是一個很是複雜而龐大的架構,固然這個架構不是一天兩天演進成這樣的,也不是一開始就設計並開發成這樣的,對於初創公司而言,很難在初期就預估到將來流量千倍、萬倍的網站架構會是怎樣的情況,同時若是初期就設計成千萬級併發的流量架構,也很難去支撐這個成本。數據庫

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

單機架構

從一個小網站提及,通常來講初始一臺服務器就夠了,文件服務器、數據庫以及應用都部署在一臺機器上。也就是俗稱的 allinone 架構。瀏覽器

多機部署

隨着網站用戶逐漸增多,訪問量愈來愈大,硬盤、cpu、內存等開始吃緊,一臺服務器難以支撐。看一下演進過程,咱們將數據服務和應用服務進行分離,給應用服務器配置更好的 cpu、內存等等,而給數據服務器配置更好、更快的大的硬盤,如圖所示用了三臺服務器進行部署,能提升必定的性能和可用性。緩存

分佈式緩存

隨着訪問的併發愈來愈高,爲了下降接口的訪問時間提升服務性能,繼續對架構進行演進。tomcat

咱們發現有不少業務數據不須要每次都從數據庫中獲取,因而咱們使用了緩存,由於 80% 的業務訪問都集中在 20% 的數據上 (二八原則),若是能將這部分數據緩存下來,性能就能提升不少,緩存又分兩種,一種是 Application 中的本地緩存,還有遠程緩存,遠程緩存又分爲遠程的單機式緩存和分佈式緩存 (圖所示的是分佈式緩存集羣)。安全

咱們須要思考幾點,具備哪一種業務特色的數據使用緩存,具備哪一種業務特色的數據使用本地緩存,具備哪一種業務特色的數據使用遠程緩存。分佈式緩存在擴容時會趕上什麼問題,如何解決,分佈式緩存的算法都有哪幾種,都有什麼優缺點。這些問題都是咱們在使用這個架構時須要思考並解決的問題。

服務器集羣

這個時候隨着訪問的 qps 不斷提升,假設咱們使用的 Application Server 是 tomcat,那麼 tomcat 服務器的處理能力就會成爲一個瓶頸,雖然咱們也能夠經過購買更強大的硬件但總會有上限,而且這個成本到後期是呈指數級的增加。

這時候就能夠對服務器作一個集羣 (cluster),而後添加負載均衡調度器 (LoadBalancer),服務器集羣后咱們就能夠橫向擴展咱們的服務器了,解決了服務器處理能力的瓶頸。

此時咱們又須要思考幾個問題, 負載均衡的調度策略都有哪些,各有什麼優缺點,各適合什麼場景,好比輪詢、權重、地址散列,地址散列又分爲原 IP 地址散列、目標 IP 地址散列、最小鏈接、加權最小鏈接等等。

服務器集羣后,假設咱們登錄了 A 服務器,session 信息存放在 A 服務器上了,若是咱們的負載均衡策略是輪詢或者最小鏈接等,下次是有可能訪問到 B 服務器,這時候存儲在 A 服務器上的 session 信息咱們在 B 服務器是讀取不到的,因此咱們須要解決 session 管理的問題。

Session 共享解決方案

session sticky

咱們使用 session sticky這種方式來解決這個問題,它的處理規則是對於同一個鏈接中的數據包,負載均衡會將其進行 NAT 轉換後,轉發至後端固定的服務器進行處理,這種方案解決了 session 共享的問題。

如圖所示客戶端 1 經過負載均衡會固定轉發到服務器 1 中。缺點是第一假設有一臺服務器重啓了,那麼該服務器的 session 將所有消失,第二是咱們的負載均衡服務器成了一種有狀態的服務器,要實現容災會有麻煩。

session 複製

session 複製,即當 browser1 通過負載均衡服務器把 session 存到 application1 中,會同時把 session 複製到 application2 中,因此多臺服務器都保存着相同的 session 信息。

缺點是應用服務器的帶寬問題,服務器之間要不斷同步 session 信息,當大量用戶在線時,服務器佔用內存會過多,不適合大規則集羣,適合機器很少狀況。

基於 cookie

基於 cookie,也就是說咱們每次都用攜帶 session 信息的 cookie 去訪問應用服務器。缺點是 cookie 的長度是有限制的,cookie 保存在瀏覽器上安全性也是一個問題。

session 服務器

把 session 作成了一個 session 服務器,好比可使用 redis 實現。這樣每一個用戶訪問到應用服務器,其 session 信息最終都存到 session server 中,應用服務器也是從 session server 中去獲取 session。

要考慮如下幾個問題,在當前架構中 session server 是一個單點的,如何解決單點,保證它的可用性,固然也能夠將 session server 作成一個集羣,這種方式適用於 session 數量及 web 服務器數量大的狀況,同時改爲這種架構後,在寫應用時,也要調整存儲 session 的業務邏輯。

數據庫讀寫分離

在解決了服務器橫向擴展以後,繼續看數據庫,數據庫的讀與寫操做都須要通過數據庫,當用戶量達到必定量時,數據庫性能又成爲了一個瓶頸,咱們繼續演進。

咱們可使用數據庫的讀寫分離,同時應用要接入多數據源。經過統一的數據訪問模型進行訪問。數據庫的讀寫分離是將全部的寫操做引入到主庫中 (master),將讀操做引入到從庫中 (slave),此時應用程序也要作出相應的變化,咱們實現了一個數據訪問模塊 (data accessmodule),使上層寫代碼的人不知道讀寫分離的存在,這樣多數據源的讀寫對業務代碼就沒有侵入,這就是代碼層面的演變。

如何支持多數據源,如何封裝對業務沒有侵入,如何使用目前業務使用的 ORM 框架完成主從的讀寫分離,是否須要更換 ORM,各有什麼優缺點,如何取捨都是當前這個架構須要考慮的問題。
當訪問量過大時候,也就是說數據庫的 IO 很是大,咱們的數據庫讀寫分離又會遇到如下問題?

例如主庫和從庫複製有沒有延遲,若是咱們將主庫和從庫分機房部署的話,跨機房傳輸同步數據更是一個問題。另外應用對數據源的路由問題,這些也是須要思考和解決的點。

CDN 加速與反向代理

咱們繼續增長了 CDN和反向代理服務器 (Reverseproxy server),使用 CDN能夠很好的解決不一樣地區訪問速度問題,反向代理則在服務器機房中能夠緩存用戶的資源。

分佈式文件服務器

這個時候咱們的文件服務器又出現了瓶頸,咱們將文件服務器改爲了分佈式文件服務器集羣,在使用分佈式文件系統時,須要考慮幾個問題,如何不影響部署在線上的應用訪問,是否須要業務部門幫忙清洗數據,是否須要備份服務器,是否須要從新作域名解析等等。

數據庫分庫分表

這個時候咱們的數據庫又出現了瓶頸,咱們選擇專庫專用的形式,進行數據的垂直拆分,相關的業務獨用本身的一個庫,咱們解決了寫數據併發量大的問題。

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

隨着訪問量過大,數據量過大,某個業務的數據庫數據量和更新量已經達到了單個數據庫的瓶頸了,這個時候就須要進行數據庫的水平拆分,例如把 user 拆分紅了 user1 和 user2,就是將同一個表的數據拆分到兩個數據庫當中,這個時候咱們解決了單數據庫的瓶頸。

水平拆分時候又要注意哪些點,都有哪幾種水平拆分的方式。進行了水平拆分後,又會遇到幾個問題,第一 sql 路由的問題,假設有一個用戶,咱們如何知道這個用戶信息是存在了 user1 仍是 user2 數據庫中,因爲分庫了,咱們的主鍵策略也會有所不一樣,同時會面臨分頁的問題,假設咱們要查詢某月份已經下單的用戶明細,而這些用戶又分佈在 user1 和 user2 庫中,咱們後臺運營管理系統對它進行展現的時候還要進行分頁。這些都是咱們在使用這個架構時須要解決的問題。

搜索引擎與 NoSQL

在網站發佈並進行了大規模的推廣後,致使咱們應用服務器的搜索量又飆升,咱們把應用服務器的搜索功能單獨抽取出來作了一個搜索引擎,同時部分場景可使用 NoSQL來提升性能。同時咱們開發一個數據統一的訪問模塊,同時連着數據庫集羣、搜索引擎和 NoSQL,解決上層應用開發的數據源問題。

後序

這裏只是簡單舉例,並無依據什麼實際的業務場景。事實上各個服務的架構是要根據實際的業務特色進行優化和演進的,因此這個過程也不是徹底相同的。固然這個架構也不是最終形態,還存在不少要提高的地方。

例如負載均衡服務器目前是一個單點的,若是負載均衡服務器訪問不了,那麼後續的包括服務器集羣等也就沒法訪問了。因此能夠將負載均衡服務器作成集羣,而後作一些主從的雙機熱備,同時作一個自動切換的解決方案。

在整個架構的演進過程當中,其實還包含更多須要關注的內容,好比安全性、數據分析、監控、反做弊......
針對一些特定的場景例如交易、充值、流計算等使用消息隊列、任務調度......
整個架構繼續發展下去,作成 SOA 架構、服務化 (微服務)、多機房......

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

END

版權申明:內容來源網絡,版權歸原創者全部。除非沒法確認,咱們都會標明做者及出處,若有侵權煩請告知,咱們會當即刪除並表示歉意。謝謝。


若是你以爲文章不錯
記得給我「點贊」和「在看」哦~

本文分享自微信公衆號 - JAVA高級架構(gaojijiagou)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索