前言html
最近一直在拜讀兩本書:算法
一、李智慧老師的《大型網站技術架構 核心原理與案例分析》數據庫
二、曾憲傑老師的《大型網站系統與Java中間件實踐》後端
看了並結合本身目前的工做進行了思考,感受獲益匪淺、受益良多,本身對大型網站的理解又有了很多的加深,下面分享一下本身的學習筆記。瀏覽器
學習筆記緩存
一、大型網站架構的發展史(紅字就是每一步發展歷程的關鍵)服務器
(1)從一個小網站發展起來,一臺服務器,應用程序、數據庫、文件等全部資源都在一臺服務器上網絡
(2)網站業務的發展,一臺服務器逐漸不能知足需求,所以要將應用和數據分離,應用和數據分離後使用三臺服務器:應用服務器、文件服務器和數據庫服務器架構
(3)網站進一步發展,數據庫壓力太大致使訪問延遲,所以使用緩存該改善網站性能(記住,使用緩存是改善網站性能的第一步),網站使用的緩存分爲兩種:緩存在應用服務器上的本地緩存和緩存在專門的分佈式緩存服務器上的遠程緩存併發
(4)使用緩存,數據庫訪問壓力獲得有效緩解,可是在網站訪問高峯期應用服務器仍是成爲了整個網站的瓶頸。這種時候要理解,不要企圖去更換更強大的服務器,對大型網站而言,無論多麼強大的服務器,都知足不了網站持續增加的業務需求,所以能夠經過增長服務器的方式改善負載壓力,再經過負載均衡調度服務器,未來自用戶瀏覽器的訪問請求分發到應用服務器集羣中的某臺服務器上
(5)雖然使用緩存可使大部分數據不走數據庫,可是緩存沒有命中、緩存過時的數據仍是會走數據庫,網站達到必定規模以後,數據庫讀寫壓力仍是會很大,成爲網站的瓶頸。此時能夠使用數據庫讀寫分離來改善數據庫負載壓力,應用服務器寫數據走寫庫,應用服務器讀數據走讀庫,目前大部分主流數據庫都提供主從熱備功能,經過配置兩臺數據庫主從關係,能夠將一臺數據庫服務器的數據更新同步到另外一臺服務器上
(6)隨着網站業務繼續發展,用戶規模不斷增大,因爲中國複雜的網絡環境,不一樣地區用戶訪問網站時,速度差異也極大。所以能夠使用反向代理和CDN,一方面加快用戶訪問速度,另外一方面減輕後端服務器的負載壓力,由於反向代理和CDN的基本原理都是緩存
(7)數據庫通過讀寫分離後,由一臺服務器拆分爲兩臺服務器,但仍是不能知足網站業務量的需求,所以能夠使用分佈式數據庫,主要拆分手段是業務分庫,將不一樣的業務數據部署在不一樣的物理服務器上
(8)大型網站爲了應對日益複雜的業務場景,可使用分而治之的手段將整個網站的業務拆分紅不一樣的應用,每一個應用獨立部署,能夠經過超級鏈創建關係,也能夠經過消息隊列進行數據分發
大型網站發展到這裏,基本上大多數的技術問題都得以解決
二、高性能網站的關鍵:控制住併發的量。只要能作到這點,不少棘手的數據問題也就不是什麼問題了
三、不要企圖經過技術解決全部問題,業務的問題也能夠經過業務手段去解決
好比12306創建之初,0點售票,網站一會兒要承受幾千萬的訪問量,直接致使12306這個網站崩潰,各路專業人士和分專業人士衆說紛紜、出謀劃策。但這僅僅經過技術能解決問題嗎?因此,針對這個需求,12306不只要改善它的技術架構,也要調整它的業務架構,不要0點售票,在售票方式上引入排隊機制、整點售票改成分時段售票,併發量控制住了,整個網站的性能就改善了
四、計算機軟件發展的 一個重要目標和驅動力是下降軟件的耦合性,事物之間關係越少,就越少彼此影響,越能夠獨立發展
五、異步架構是典型的生產者消費者模式
六、使用異步隊列有幾個好處
(1)提升系統的可用性
(2)加快網站的訪問速度
(3)消除併發訪問高峯
七、網站伸縮性就是指經過不斷向集羣中加入服務器的手段來緩解不斷上升的用戶併發訪問壓力和不斷增加的數據存儲需求
八、衡量架構伸縮性的指標
(1)是否可用多臺服務器架構集羣
(2)是否容易向服務器中添加新的服務器
(3)加入的服務器是否能夠提供和原服務器無差異的服務
(4)集羣中容納的總服務器是否有限制
九、反應系統忙閒的重要指標Load
System Load也稱爲Load,即系統負載,指當前正在被CPU執行和等待被CPU執行的線程數之和,,是反映系統忙閒程度的重要指標。多核CPU下,完美狀況應該是全部CPU都在用,沒有線程等待處理。Load值低於CPU數目,表示CPU有空閒,資源存在浪費;Load值高於CPU數目,表示進程在等待CPU調度,資源存在不足
十、瀏覽器訪問優化手段
(1)減小http請求,合併CSS、JS、圖片,不要發起屢次http請求去拿這些數據
(2)使用瀏覽器緩存,存儲靜態資源,Cache-Control、Expires、Pragma、Last_Modified都是和緩存的HTTP HEADER
(3)啓用壓縮,有效減低通訊傳輸的數據量
(4)CSS放在上面、JS放在下面,由於JS下載會當即執行,可能阻塞頁面加載速度
(5)減小Cookie傳輸
十一、緩存使用的幾點細節
(1)頻繁修改的數據不要寫緩存,通常讀寫比例至少2:1以上纔會作緩存,即一次寫入至少有兩次以上的讀取,像新浪微博這種,熱門微博,一次寫入可能會被讀取數百萬次,那是大大地合算
(2)若是訪問沒有熱點,大部分數據的訪問沒有集中在小部分數據上,那麼作緩存就沒有意義,由於緩存有失效機制,大部分數據尚未被再次訪問就被擠出緩存了
(3)容忍必定時間的數據不一致,除非數據更新時馬上通知緩存,不過這也會帶來開銷與事物一致性的問題
(4)使用分佈式緩存集羣以提升緩存可用性
(5)新啓動的緩存沒有任何數據,在重建緩存的過程當中,系統性能與數據庫負載都不太好,所以要根據項目、根據業務,將一部分數據在啓動時就加載好,這就是緩存預熱
(6)對緩存作無效參數並設置失效時間,避免不恰當的業務或惡意攻擊頻繁調用接口查詢數據庫,一旦某一個Key值數據庫裏面查不到數據就進入無效緩存,一段時間內再次訪問這個Key值無數據返回
十二、消息隊列具備很好的削峯做用(前面提過),不過注意須要適當修改業務流程進行配合
經過異步處理,將短期高併發產生的事物消息存儲在消息隊列中,從而能夠削平高峯期的併發事物。不過要注意點,因爲數據寫入消息隊列後當即返回給用戶,數據在後續的業務校驗、寫數據庫等操做可能失敗,所以在使用消息隊列進行業務異步處理後,,須要適當修改業務流程進行配合,如訂單提交以後,訂單數據寫入消息隊列,不能當即返回給用戶訂單提交成功,須要在消息隊列的訂單消費者進程真正處理完該訂單的,甚至商品出庫後,再經過電子郵件或者SMS消息通知用戶訂單成功,避免交易糾紛
1三、CDN和反向代理的基本原理都是緩存,區別在於CDN部署在網絡提供商的機房,使用戶在請求網站服務時,能夠從距離本身最近的網絡提供商機房獲取數據;反向代理則部署在網站的中心機房,當用戶請求到達中心機房時,首先訪問的是反向代理服務器,若是反向代理服務器中緩存着用戶請求的資源,就將其直接返回給用戶。使用CDN和反向代理的目的是同樣的:
(1)儘早返回速度給用戶,加快用戶訪問網站的速度
(2)減輕後端服務器的負載壓力
1四、應用服務器集羣的Session管理
單機環境下,Session可由部署在服務器上的Web容器管理,在使用負載均衡的集羣環境中,因爲負載均衡服務器可能會將請求分發到集羣任何一臺應用服務器上,因此保證每次請求依然可以得到正確的Session比單機時要複雜得多。集羣環境下,Session管理有如下手段:
一、Session複製
在集羣中的幾臺服務器之間同步Session對象,使得每臺服務器上都保存着全部用戶的Session信息,這樣任何一臺機器宕機都不會致使Session數據的丟失,而服務器使用Session時,也只須要從本機獲取便可。
這種方案雖然簡單,從本機讀取Session信息也很快,但只能使用在集羣規模比較小的狀況下。當集羣規模較大時,集羣服務器之間須要大量的通訊進行Session複製,佔用服務器和網絡的大量資源,系統不堪負擔。並且因爲全部用戶的Session在每臺服務器都有備份,在大量用戶訪問的狀況下,甚至會出現服務器內存不夠Session使用的狀況。
大型網站的核心應用集羣就是數千臺服務器,同時在線用戶達到數千萬,並不適用這種方案。
二、Session綁定
Session綁定能夠利用負載均衡的原地址Hash算法,負載均衡服務器老是未來源於同一IP的請求分發到同一臺服務器。這樣在整個會話期間,用戶全部請求都在同一臺服務器上處理,即Session綁定在某臺特定服務器上,保證Session總能在這臺服務器上獲取,這種方法又被稱爲會話粘滯。
可是Session綁定的方案不符合對系統高可用的需求,由於一旦某臺服務器宕機,那麼該機器上的Session也就不復存在了,用戶請求切換到其餘機器後由於沒有Session而沒法完成業務處理。所以雖然大部分負載均衡服務器都提供原地址負載均衡算法,但不多有網站利用這個算法進行Session管理
三、利用Cookie記錄Session
早期的企業應用使用C/S架構,一種管理Session的方式是將Session記錄在客戶端,每次請求服務器的時候,將Session放在請求中發送給服務器,服務器處理完請求後再將修改過的Session響應給客戶端。網站沒有客戶端,可是能夠利用瀏覽器支持的Cookie記錄Session。
利用Cookie記錄Session也有一些缺點:
(1)受到Cookie大小限制,能記錄的信息有限
(2)每次請求和響應都攜帶Cookie,影響性能
(3)若是用戶關閉Cookie,訪問就會不正常
不過由於Cookie簡單易用且可用性高,支持應用服務器的線性伸縮,而大部分應用須要記錄的Session信息有比較小,所以事實上,許多網站或多 或少都會使用Cookie記錄Session
四、Session服務器
利用獨立部署的Session服務器(集羣)統一管理Session,應用服務器每次讀寫Session時,都訪問Session服務器。
這種解決方案事實上是將應用服務器的狀態分離,分爲無狀態的應用服務器和有狀態的Session服務器,而後針對這兩種服務器的不一樣特性分別設計其架構。
對於有狀態的Session服務器,一種比較簡單的方法是利用分佈式緩存、數據庫等,在這些產品的基礎上進行包裝,使其符合Session的存儲和訪問要求;若是業務場景對Session管理有比較高的要求,那麼就要利用Session服務集成單點登陸(SSO)、用戶服務等功能,則須要開發專門的Session服務管理平臺。