一個成熟的大型網站架構並非一開始就設計的很是完美,也不是一開始就具有高性能、高可用、安全性等特性,而是隨着用戶量的增長,業務功能的擴展逐步完善演變過來的。在這個過程當中,開發模式、技術架構等都會發生很是大的變化。而針對不一樣業務特徵的系統,會有各自的側重點,好比像淘寶這類的網站,要解決的是海量商品搜索、下單、支付等問題;騰訊,要解決的是數億級別用戶的實時消息傳輸;百度所要解決的是海量數據的搜索。程序員
架構是演變而來的,不是設計出來的。沒有最好的架構,只有最適合的架構。web
下面以一個簡單的電商系統爲例,當數據量、訪問量提高,觀察這個系統可能會發生的結構變化。假如咱們系統具有如下功能:用戶模塊(用戶註冊和管理),商品模塊(商品展現和管理),交易模塊(建立交易及支付結算)。redis
階段一,單應用架構sql
網站的初期也能夠認爲是互聯網發展的早起,咱們常常會在單機上跑咱們全部的程序和軟件。把全部軟件和應用都部署在一臺機器上,這樣就完成一個簡單系統的搭建,這個時候的講究的是效率。數據庫
階段二,應用服務器和數據庫服務器分離緩存
隨着網站的上線,訪問量逐步上升,服務器的負載慢慢提升,在服務器尚未超載的時候,咱們應該作好規劃,提高網站的負載能力。假如代碼層面的優化已經沒辦法繼續提升,在不提升單臺機器的性能,增長機器是一個比較好的方式,投入產出比很是高。這個階段增長機器的主要目的是將web 服務器和數據庫服務器拆分,這樣不只提升了單機的負載能力,也提升了容災能力。安全
階段三,應用服務器集羣服務器
隨着訪問量的繼續增長,單臺應用服務器已經沒法知足需求。在假設數據庫服務器尚未遇到性能問題的時候,咱們能夠增長應用服務器,經過應用服務器集羣將用戶請求分流到各個服務器中,從而繼續提高負載能力。此時多臺應用服務器之間沒有直接的交互,他們都是依賴數據庫各自對外提供服務。多線程
架構發展到這個階段,各類問題也會慢慢呈現,好比用戶請求由誰來轉發到具體的應用服務器,這時候可能會出現下面的架構模型。架構
階段四,數據庫讀寫分離
當數據庫壓力變大時,那麼怎麼去提升數據庫層面的負載呢?有了前面的思路之後,天然會想到增長服務器。可是假如咱們單純的把數據庫一分爲二,而後對於後續數據庫的請求,分別負載到兩臺數據庫服務器上,那麼必定會形成數據庫不統一的問題。因此咱們通常先考慮讀寫分離的方式。
階段五,使用搜索引擎緩解讀庫的壓力
數據庫作讀庫的話,經常對模糊查找效率不是特別好,像電商類的網站,搜索是很是核心的功能,即使是作了讀寫分離,這個問題也不能有效解決。那麼這個時候能夠引入搜索引擎,使用搜索引擎可以大大提升咱們的查詢速度。
若是你是Java程序員,若是你想提高本身,若是你想變強,加q羣:479499375,可獲取一份Java架構進階技術精品視頻。(高併發+Spring源碼+JVM原理解析+分佈式架構+微服務架構+多線程併發原理等...這些成爲架構師必備的內容)以及Java進階學習路線圖。
階段六,引入緩存機制緩解數據庫的壓力
隨着訪問量的持續增長,逐漸出現許多用戶訪問同一部份內容的狀況。對於這些熱點數據,不必每次都從數據庫去讀取,咱們可使用緩存技術,好比memcache、redis 來做爲咱們應用層的緩存;另外在某些場景下,好比咱們對用戶的某些IP 的訪問頻率作限制,那這個放內存中又不合適,放數據庫又太麻煩,這個時候可使用Nosql 的方式好比mongDB 來代替傳統的關係型數據庫。
階段七,數據庫的水平/垂直拆分
咱們的網站演進的變化過程,交易、商品、用戶的數據都還在同一個數據庫中,儘管採起了增長緩存,讀寫分離的方式,可是隨着數據庫的壓力持續增長,數據庫的瓶頸仍然是個最大的問題。所以咱們能夠考慮對數據的垂直拆分和水平拆分。
垂直拆分:把數據庫中不一樣業務數據拆分到不一樣的數據庫。
水平拆分:把同一個表中的數據拆分到兩個甚至更多的表中。
階段八,應用的拆分
隨着業務的發展,業務愈來愈多,應用的壓力愈來愈大,工程規模也愈來愈龐大。這個時候就能夠考慮將應用拆分,按照領域模型將系統拆成用戶、商品、交易子系統。
這樣拆分之後,可能會有一些相同的代碼,好比用戶操做,在商品和交易都須要查詢,因此會致使每一個系統都會有用戶查詢訪問相關操做。這些相同的操做必定是要抽象出來,能夠經過服務化的方式來解決。
階段九,服務化
服務拆分之後,各個服務之間能夠經過RPC 技術進行通訊,比較典型的有:webservice、hessian、http、RMI等。