網站性能是客觀的指標,可以具體體現在響應時間、吞吐量等技術指標,同時也是一種主觀感受。
網站性能測試
網站性能視角
性能測試是性能優化的前提和基礎,也是性能優化結果的檢查和度量標準。
用戶視角
從用戶角度,網站性能就是在瀏覽器上直觀感受到的網站響應速度。
原因:
1、不用計算機的性能差異;
2、不同瀏覽器解析HTML速度的差異;
3、不同網絡運營商提供的互聯網帶寬服務的差異;等
優化手段:
採用前端架構優化,比如:
1、通過優化頁面HTML樣式;
2、利用瀏覽器端的併發和異步特性;
3、調整瀏覽器緩存策略;
4、使用CDN;
5、使用反向代理;等
開發人員視角
開發人員關注的主要是應用程序本身及其相關子系統的性能,包括:響應延遲、系統吞吐量、併發處理能力、系統穩定性等。
優化手段:
1、使用緩存加速數據讀取;
2、使用集羣提高吞吐能力;
3、使用異步消息加快請求響應,及實現削峯
4、代碼優化;等
運維人員視角
運維人員關注基礎設施性能和資源利用率,如網絡運營商的帶寬能力、服務器硬件配置、數據中心網絡架構、服務器和網絡帶寬的資源利用率等。
優化手段:
1、建設優化骨幹網;
2、使用高性價比定製服務器;
3、利用虛擬化技術優化資源利用率;等
網站性能指標
網站性能測試的主要指標有:響應時間、併發數、吞吐量、性能計數器等。
1、響應時間
響應時間是指應用執行一個操作需要的實際那,包括從發出請求開始到收到最後響應數據所需要的時間。
測試程序一般通過重複請求,計算得到單次請求的響應時間。
2、併發數
併發數是指系統能夠同時處理請求的數目,也反映了系統的負載特性。
測試程序通過多線程模擬併發用戶的辦法來測試系統的併發處理能力,並在兩次請求之間加入一個隨機等待時間。
3、吞吐量
吞吐量是指單位時間內系統處理的請求數量,體現系統的整體處理能力。
常量化指標:TPS(每秒事務數)、HPS(每秒HTTP請求數)、QPS(每秒查詢數)。
4、性能計數器
性能計數器是描述服務器或操作系統性能的一些數據指標。包括:System Load、對象與線程數、內存使用、 CPU使用、磁盤與網絡I/O等指標。運維可對其設置報警閾值。
System Load(系統負載):指當前正在被CPU執行和等待被CPU執行的進程數目總和。Load的理想值是CPU的數目。
性能測試方法
性能測試可分爲:性能測試、負載測試、壓力測試、穩定性測試。
性能優化
性能優化根據網站的分層架構,可分爲:Web前端性能優化、應用服務器性能優化、存儲服務器性能優化等。
Web前端性能優化
Web前端主要包括:瀏覽器加載、網站視圖模型、圖片服務、CDN服務等,主要優化手段包括:瀏覽器訪問優化、使用反向代理、使用CDN加速等
1、瀏覽器訪問優化
(1)減少HTTP請求
HTTP協議是無狀態的應用層協議,每次HTTP請求都要建立通信鏈路,進行數據傳輸;在服務器端,每個HTTP請求都需要啓動獨立線程來處理。
減少HTTP的主要手段:合併CSS、合併JavaScript、合併圖片。如果每張圖片都有不同的超鏈接,可通過CSS偏移響應鼠標點擊操作,構造不同的URL。
(2)使用瀏覽器緩存
將網站的靜態資源如:CSS、JS、Logo、圖標等,緩存在瀏覽器中。通過設置HTTP頭中Cache-Control和Expires的屬性,設定瀏覽器緩存,以及緩存時間。
如果採用了瀏覽器緩存,若靜態資源文件變化需要及時應用到客戶端瀏覽器,則可通過改變文件名以實現。
瀏覽器緩存策略在更新靜態資源時,採用逐量更新的方法,避免瀏覽器突然大量緩存失效,造成服務器負載驟增,網絡堵塞等情況。
(3)啓用壓縮
在服務器端對文件進行壓縮、在瀏覽器端對文件進行解壓,可有效減少通信傳輸數據量。
但壓縮、解壓會對服務器、瀏覽器造成壓力,需權衡考慮。
(4)CSS放在頁面最上方、JavaScript放在頁面最下面
瀏覽器加載JS後立即執行,有可能會阻塞整個頁面加載。
如果頁面解析時就需要用到JS,則應該放在頁面上方。
(5)減少cookie傳輸
Cookie包含在每次請求和響應中,太大的cookie會嚴重影響數據傳輸;
對靜態資源的訪問,發送cookie沒有意義,因此可以讓靜態資源使用獨立域名訪問,避免發送cookie。
2、CDN加速
CDN部署在網絡運營商的機房,用戶請求路由的第一條就到達了CDN服務器,因此可以將CDN作爲緩存,存放靜態資源,如:圖片、文件、CSS、Script腳本、靜態網頁等,可以極大的改善網頁的打開速度。
3、反向代理
反向代理位於網站機房一側,代理網站Web服務器接收HTTP請求,來自互聯網的訪問請求必須經過代理服務器,具有保護網站安全的作用。
代理服務器可以通過配置緩存功能加速Web請求,靜態內容和動態內容都會被緩存。動態內容發生改變時,通過內部機制通過反向代理緩存失效,反向代理會重新加載最新的動態內容。
應用服務器性能優化
應用服務器是處理網站業務的服務器,網站的業務代碼部署在這裏,優化手段有:緩存、集羣、異步等。
1、分佈式緩存
緩存的本質是一個內存Hash表。
(1)分佈式緩存架構
分佈式緩存指緩存部署在多個服務器組成的集羣中,以集羣方式提供緩存服務,其架構有兩種:一種以JBoss Cache爲代表的需要更新同步的分佈式緩存、一種以Memcached爲代表的不互相通信的分佈式緩存。
1)JBoss Cache
在集羣中所有服務器中保存相同的緩存數據,當某臺服務器有緩存數據更新,會通知集羣中其他機器更新緩存數據或清除緩存數據。
JBoss Cache通常將應用程序和緩存部署在同一臺服務器上,這是因爲應用程序可以快速獲取緩存數據。
缺陷:緩存數據的數量受限於單一服務器的內存空間;當集羣規模較大的時候,緩存更新信息需要同步到集羣所有機器,代價太大。
2)Memcached
Memcached是一種集中式的緩存集羣管理,即互不通信的分佈式架構方式。
其將緩存與應用程序分離部署:緩存系統部署在一組專門的服務器上;應用程序通過一致性Hash等路由算法選擇緩存服務器遠程訪問緩存數據。
優點:擴展性好、伸縮性好、可存儲海量數據。
a、簡單的通信協議
遠程通信需要考慮兩方面問題:一是通信協議,即選擇TCP協議還是UDP協議,還是HTTP協議;二是通信序列化協議,如:XML、JSON等文本序列化協議,還是Google Protobuffer等二進制序列化協議。
Memcached使用TCP協議作爲通信協議,使用一套基於文本的自定義協議作爲序列化協議(以一個命令開頭,後面是一組命令操作數,如:get<key>)。
b、高性能的網絡通信
Memcached服務端通信模塊基於Libevent,一個支持事件觸發的網絡通信程序庫。
特點:Libevent在長連接方面表現穩定。
c、高效的內存管理
內存管理中的難題主要是內存碎片。
Memcached使用固定內存分配機制。其原理是:將內存空間分爲一組slab,每個slab裏又包含一組chunk,同一個slab裏的每個chunk的大小是固定的,擁有相同大小的chunk的slab被組織在一起,稱爲slab_class。存儲數據時,根據數據的size大小,尋找一個大於size的最小chunk將數據寫入。
2、異步操作
使用消息隊列將調用異步化,可改善網站的擴展性、系統的性能。
通過在應用服務器和數據庫服務器之間加入消息隊列服務器。
消息隊列服務器處理速度遠大於數據庫服務器,可以使用戶的響應延遲得到改善;消息隊列具有很好的削峯作用——即通過異步處理,將短時間高併發產生的事務消息存儲在消息隊列中,從而削平高峯期的併發事務。
補充:使用消息隊列進行業務異步處理後,需要適當修改業務流程進行配合,因爲用戶接收到響應時,可能其消息還未被處理。
3、使用集羣
在網站高併發訪問時,使用負載均衡技術爲一個應用構建一個由多臺服務器組成的服務器集羣,將併發訪問請求分發到多臺服務器上處理。
4、代碼優化
(1)多線程
採用多線程的方式響應併發用戶請求。
線程安全解決手段:
a、將對象設計爲無狀態對象
無狀態對象是指對象本身不存儲狀態信息,使得多線程併發訪問時不會出現狀態不一致。Java Web中的servlet對象就是無狀態對象。Web開發中常用的貧血模型對象也是無狀態對象。
b、使用局部對象
在方法內部創建對象,可避免對象在線程間傳遞
c、併發訪問資源時使用鎖
在多線程訪問資源時,通過鎖的方式使線程併發操作轉化爲順序操作,避免資源被併發修改。
缺點:鎖機制會導致同步順序執行,會對系統性能產生嚴重影響。
(2)資源複用
系統運行時,儘量減少那些開銷很大的系統資源的創建和銷燬,如:數據庫連接、網絡通信連接、線程、複雜對象等。
資源複用的兩種模式:單例、對象池。
a、單例
b、對象池
比如數據庫連接,頻繁創建關閉數據庫連接,對數據庫服務器而言是災難性的,並且需要花費較長的時間。
對象池模式:數據庫連接創建之後,將連接對象放入對象池容器中,應用程序需要連接時,就從對象池中獲取一個空閒的連接使用,使用完後歸還到對象池中。
比如HTTP請求,同樣可以創建一個線程池。
(3)數據結構
緩存的本質是Hash表。字符串Hash散列算法:Time33算法——對字符串逐字符串迭代乘以33,求得Hash值。
(4)垃圾回收
如果Web應用運行在JVM等具有垃圾回收功能的環境中,那麼垃圾回收可能會對系統的性能特性產生巨大影響。
存儲性能優化
1、機械硬盤 VS 固態硬盤
機械硬盤具有快速順序讀寫、慢速隨機讀寫的訪問特性。
2、B+樹 VS LSM樹
(1)B+樹
針對機械硬盤特性的一種算法,保證數據在不斷更新、插入、刪除後依然有序,從而加快數據檢索速度。
原理:本質是N叉排序樹。以樹節點爲單位存儲在磁盤中,從根開始查找所需數據所在的節點編號和磁盤位置,將其加載到內存中然後繼續查找,直到找到所需的數據。
目前數據庫多采用兩級索引的B+樹,樹的層次最多三層。
(2)LSM樹
很多NoSQL產品使用的數據結構。
原理:本質是一個N階合併樹。數據寫操作(包括插入、修改、刪除)都在內存中進行,並且都會創建一個新紀錄(修改會記錄新的數據值,刪除會記錄一個刪除標識),這些數據在內存中仍然還是一棵排序樹,當數據量超過設定的內存閾值後,會將這棵排序樹與磁盤上最新的排序樹合併。當這棵排序樹的數據量也超過設定閾值後,和磁盤上的下一級的排序樹合併。合併過程中,會用最新的數據覆蓋舊的數據(或者記錄爲不同的版本)。
3、RAID VS HDFS
(1)RAID
RAID(廉價磁盤冗餘陣列)主要是是爲了改善磁盤的訪問延遲,增強磁盤的可用性和容錯能力。通過使用RAID技術,實現數據在多塊磁盤上併發讀寫和數據備份。
RAID技術分爲:RAID0、RAID1、RAID10、RAID5、RAID6
a、RAID0
優點:數據在從內存緩衝區寫入磁盤時,根據磁盤數量將數據分成N份,這些數據同時併發寫入N塊磁盤,實現N倍加速。
缺點:RAID0不做數據備份,N塊磁盤中只要有一塊損壞,數據完整性就被破壞,所有數據都會損壞
b、RAID1
優點:數據寫入磁盤時,將一份數據同時寫入兩塊磁盤,即使有一塊磁盤損壞,也能通過插入一塊新磁盤複製數據自動修復,可靠性較高。
c、RAID10
綜合RAID0和RAID1,將所有磁盤平均分成兩份,數據同時在兩份磁盤寫入,同時進行N等分同時寫數據,提速N倍。
缺點:磁盤利用率底。
d、RAID3
在數據寫入磁盤時,將數據分成N-1份,併發寫入N-1塊磁盤,並在第N塊磁盤記錄校驗數據,任何一塊磁盤損壞(包括校驗數據磁盤),都可以利用其它N-1
塊磁盤的數據恢復。
缺點:第N塊磁盤頻繁寫,導致容易損壞。
e、RAID5
和RAID3相似,校驗數據不是寫在第N塊磁盤,而是螺旋式地寫入所有磁盤中。避免頻繁寫一塊磁盤。
f、RAID6
和RAID5相似,數據只寫入N-2塊磁盤,並螺旋式地在兩塊磁盤中寫入校驗信息,
總結,RAID技術在傳統關係數據庫及文件系統中應用比較廣泛,但是在大型網站比較喜歡使用NoSQL,以及分佈式文件系統中,RAID不合適。
(2)HDFS
HDFS(Hadoop分佈式文件系統)中,系統在整個存儲集羣的多臺服務器上進行數據併發讀寫和備份。
HDFS以塊(Block)爲單位管理文件內容,一個文件被分割成若干個Block,當應用程序寫文件時,每寫完一個Block,HDFS將其自動複製到另外兩臺機器上,保證每個Block有三個副本。類似於RAID1.
當對文件進行處理計算時,通過MapReduce併發計算任務框架,可以啓動多個計算子任務(MapReduce Task),同時讀取文件的多個Block,併發處理。類似於RAID0.
結構:HDFS有兩種重要的服務器角色:NameNode(名字服務節點)、DataNode(數據存儲節點)。
NameNode:在整個HDFS中只部署一個實例,提供元數據服務,管理文件名Block(默認64M)的分配,維護整個文件系統的目錄樹結構,相當於操作系統中的文件分配表(FAT)。
DataNode:部署在HDFS集羣中其他所有服務器上,提供真正的數據存儲服務。
工作原理:應用程序寫文件時,首先訪問NameNode,請求分配數據塊,NameNode根據管理的DataNode服務器的磁盤空間,按照一定的負載均衡策略,分配若干數據塊提供使用。當寫完一個數據塊時,HDFS將該數據塊複製兩份存儲在其他DataNode服務器上。一旦某臺服務器宕機,系統會自動利用其他機器上的數據將這臺服務器上存儲的數據塊自動再備份一份,提高可靠性。
HDFS配合MapReduce等並行計算框架進行大數據處理時,可以在整個集羣上併發讀寫訪問所有磁盤。
【參考文獻】大型網站技術架構核心原理與案例分析,李智慧,電子工業出版社