做者:若汐緣
https://www.jianshu.com/p/796...
以淘寶網爲例,簡單瞭解一下大型電商的服務端架構是怎樣的。如圖所示
最上面的就是安全體系系統,中間的就是業務運營系統,包含各個不一樣的業務服務,下面是一些共享服務,而後還有一些中間件,其中 ECS 就是雲服務器,MQS 是隊列服務,OCS 是緩存等等,右側是一些支撐體系服務。java
除圖中所示以外還包含一些咱們看不到的,好比高可用的體現。淘寶目前已經實現多機房容災和異地機房單元化部署,爲淘寶的業務也提供了穩定、高效和易於維護的基礎架構支撐。web
這是一個含金量很是高的架構,也是一個很是複雜而龐大的架構,固然這個架構不是一天兩天演進成這樣的,也不是一開始就設計並開發成這樣的,對於初創公司而言,很難在初期就預估到將來流量千倍、萬倍的網站架構會是怎樣的情況,同時若是初期就設計成千萬級併發的流量架構,也很難去支撐這個成本。面試
所以一個大型服務系統,都是從小一步一步走過來的,在每一個階段找到對應該階段網站架構所面臨的問題,而後不斷解決這些問題,在這個過程當中,整個架構會一直演進,同時內含的代碼也就會演進,大到架構、小到代碼都是在不斷演進和優化的。因此說高大上的項目技術架構和開發設計實現不是一蹴而就的,這是所謂的萬丈高樓平地起。redis
從一個小網站提及,通常來講初始一臺服務器就夠了,文件服務器、數據庫以及應用都部署在一臺機器上。也就是俗稱的 allinone
架構。算法
隨着網站用戶逐漸增多,訪問量愈來愈大,硬盤、cpu、內存等開始吃緊,一臺服務器難以支撐。看一下演進過程,咱們將數據服務和應用服務進行分離,給應用服務器配置更好的 cpu、內存等等,而給數據服務器配置更好、更快的大的硬盤,如圖所示用了三臺服務器進行部署,能提升必定的性能和可用性。sql
隨着訪問的併發愈來愈高,爲了下降接口的訪問時間提升服務性能,繼續對架構進行演進。數據庫
咱們發現有不少業務數據不須要每次都從數據庫中獲取,因而咱們使用了緩存,由於 80% 的業務訪問都集中在 20% 的數據上 (二八原則),若是能將這部分數據緩存下來,性能就能提升不少,緩存又分兩種,一種是 Application 中的本地緩存,還有遠程緩存,遠程緩存又分爲遠程的單機式緩存和分佈式緩存 (圖所示的是分佈式緩存集羣)。後端
咱們須要思考幾點,具備哪一種業務特色的數據使用緩存,具備哪一種業務特色的數據使用本地緩存,具備哪一種業務特色的數據使用遠程緩存。分佈式緩存在擴容時會趕上什麼問題,如何解決,分佈式緩存的算法都有哪幾種,都有什麼優缺點。這些問題都是咱們在使用這個架構時須要思考並解決的問題。瀏覽器
關注微信公衆號:Java技術棧,在後臺回覆:架構,能夠獲取我整理的 N 篇最新架構乾貨。緩存
這個時候隨着訪問的 qps 不斷提升,假設咱們使用的 Application Server 是 tomcat,那麼 tomcat 服務器的處理能力就會成爲一個瓶頸,雖然咱們也能夠經過購買更強大的硬件但總會有上限,而且這個成本到後期是呈指數級的增加。
這時候就能夠對服務器作一個集羣 (cluster)
,而後添加負載均衡調度器 (LoadBalancer)
,服務器集羣后咱們就能夠橫向擴展咱們的服務器了,解決了服務器處理能力的瓶頸。
此時咱們又須要思考幾個問題, 負載均衡的調度策略都有哪些,各有什麼優缺點,各適合什麼場景,好比輪詢、權重、地址散列,地址散列又分爲原 IP 地址散列、目標 IP 地址散列、最小鏈接、加權最小鏈接等等。
服務器集羣后,假設咱們登錄了 A 服務器,session 信息存放在 A 服務器上了,若是咱們的負載均衡策略是輪詢或者最小鏈接等,下次是有可能訪問到 B 服務器,這時候存儲在 A 服務器上的 session 信息咱們在 B 服務器是讀取不到的,因此咱們須要解決 session 管理的問題。
咱們使用 session sticky
這種方式來解決這個問題,它的處理規則是對於同一個鏈接中的數據包,負載均衡會將其進行 NAT 轉換後,轉發至後端固定的服務器進行處理,這種方案解決了 session 共享的問題。
如圖所示客戶端 1 經過負載均衡會固定轉發到服務器 1 中。缺點是第一假設有一臺服務器重啓了,那麼該服務器的 session 將所有消失,第二是咱們的負載均衡服務器成了一種有狀態的服務器,要實現容災會有麻煩。
session 複製,即當 browser1 通過負載均衡服務器把 session 存到 application1 中,會同時把 session 複製到 application2 中,因此多臺服務器都保存着相同的 session 信息。
缺點是應用服務器的帶寬問題,服務器之間要不斷同步 session 信息,當大量用戶在線時,服務器佔用內存會過多,不適合大規則集羣,適合機器很少狀況。
基於 cookie,也就是說咱們每次都用攜帶 session 信息的 cookie 去訪問應用服務器。缺點是 cookie 的長度是有限制的,cookie 保存在瀏覽器上安全性也是一個問題。
把 session 作成了一個 session 服務器,好比可使用 redis 實現。這樣每一個用戶訪問到應用服務器,其 session 信息最終都存到 session server 中,應用服務器也是從 session server 中去獲取 session。
要考慮如下幾個問題,在當前架構中 session server 是一個單點的,如何解決單點,保證它的可用性,固然也能夠將 session server 作成一個集羣,這種方式適用於 session 數量及 web 服務器數量大的狀況,同時改爲這種架構後,在寫應用時,也要調整存儲 session 的業務邏輯。
在解決了服務器橫向擴展以後,繼續看數據庫,數據庫的讀與寫操做都須要通過數據庫,當用戶量達到必定量時,數據庫性能又成爲了一個瓶頸,咱們繼續演進。
咱們可使用數據庫的讀寫分離,同時應用要接入多數據源。經過統一的數據訪問模型進行訪問。數據庫的讀寫分離是將全部的寫操做引入到主庫中 (master)
,將讀操做引入到從庫中 (slave)
,此時應用程序也要作出相應的變化,咱們實現了一個數據訪問模塊 (data accessmodule)
,使上層寫代碼的人不知道讀寫分離的存在,這樣多數據源的讀寫對業務代碼就沒有侵入,這就是代碼層面的演變。
如何支持多數據源,如何封裝對業務沒有侵入,如何使用目前業務使用的 ORM 框架完成主從的讀寫分離,是否須要更換 ORM,各有什麼優缺點,如何取捨都是當前這個架構須要考慮的問題。
當訪問量過大時候,也就是說數據庫的 IO 很是大,咱們的數據庫讀寫分離又會遇到如下問題?
例如主庫和從庫複製有沒有延遲,若是咱們將主庫和從庫分機房部署的話,跨機房傳輸同步數據更是一個問題。另外應用對數據源的路由問題,這些也是須要思考和解決的點。
咱們繼續增長了 CDN
和反向代理服務器 (Reverseproxy server)
,使用 CDN
能夠很好的解決不一樣地區訪問速度問題,反向代理則在服務器機房中能夠緩存用戶的資源。
這個時候咱們的文件服務器又出現了瓶頸,咱們將文件服務器改爲了分佈式文件服務器集羣,在使用分佈式文件系統時,須要考慮幾個問題,如何不影響部署在線上的應用訪問,是否須要業務部門幫忙清洗數據,是否須要備份服務器,是否須要從新作域名解析等等。
這個時候咱們的數據庫又出現了瓶頸,咱們選擇專庫專用的形式,進行數據的垂直拆分,相關的業務獨用本身的一個庫,咱們解決了寫數據併發量大的問題。
當咱們把這些表分紅不一樣的庫,又會帶來一些新的問題。例如跨業務和跨庫的事務,可使用分佈式事務,或者去掉事務,或者不追求強事務。
隨着訪問量過大,數據量過大,某個業務的數據庫數據量和更新量已經達到了單個數據庫的瓶頸了,這個時候就須要進行數據庫的水平拆分,例如把 user 拆分紅了 user1 和 user2,就是將同一個表的數據拆分到兩個數據庫當中,這個時候咱們解決了單數據庫的瓶頸。
水平拆分時候又要注意哪些點,都有哪幾種水平拆分的方式。進行了水平拆分後,又會遇到幾個問題,第一 sql 路由的問題,假設有一個用戶,咱們如何知道這個用戶信息是存在了 user1 仍是 user2 數據庫中,因爲分庫了,咱們的主鍵策略也會有所不一樣,同時會面臨分頁的問題,假設咱們要查詢某月份已經下單的用戶明細,而這些用戶又分佈在 user1 和 user2 庫中,咱們後臺運營管理系統對它進行展現的時候還要進行分頁。這些都是咱們在使用這個架構時須要解決的問題。
在網站發佈並進行了大規模的推廣後,致使咱們應用服務器的搜索量又飆升,咱們把應用服務器的搜索功能單獨抽取出來作了一個搜索引擎,同時部分場景可使用 NoSQL
來提升性能。同時咱們開發一個數據統一的訪問模塊,同時連着數據庫集羣、搜索引擎和 NoSQL
,解決上層應用開發的數據源問題。
關注微信公衆號:Java技術棧,在後臺回覆:架構,能夠獲取我整理的 N 篇最新架構乾貨。
這裏只是簡單舉例,並無依據什麼實際的業務場景。事實上各個服務的架構是要根據實際的業務特色進行優化和演進的,因此這個過程也不是徹底相同的。固然這個架構也不是最終形態,還存在不少要提高的地方。
例如負載均衡服務器目前是一個單點的,若是負載均衡服務器訪問不了,那麼後續的包括服務器集羣等也就沒法訪問了。因此能夠將負載均衡服務器作成集羣,而後作一些主從的雙機熱備,同時作一個自動切換的解決方案。
在整個架構的演進過程當中,其實還包含更多須要關注的內容,好比安全性、數據分析、監控、反做弊......
針對一些特定的場景例如交易、充值、流計算等使用消息隊列、任務調度......
整個架構繼續發展下去,作成 SOA 架構、服務化 (微服務)、多機房......
最後,我想說高大上的項目技術架構和開發設計實現毫不是一僦而就的。
推薦去個人博客閱讀更多:
2.Spring MVC、Spring Boot、Spring Cloud 系列教程
3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程
生活很美好,明天見~