網站架構中最核心的幾個要素包括:性能,可用性,伸縮性,擴展性和安全性,而性能又是其中最爲重要的,本篇簡要說下網站性能優化方面所需作的一些事情;前端
性能問題 | 說明 |
產生緣由 | 大都是在用戶高併發訪問時產生的 |
主要工做 | 改善高併發用戶訪問狀況下的網站訪問速度 |
主要目的 | 改善用戶體驗,讓用戶以爲網站很快,一切的產品都必須站在用戶的角度考慮問題 |
站在不一樣的視角,所關注的網站性能是不一致的:python
視角 | 關注點 | 說明 |
用戶視角 | 用戶打開瀏覽器網頁的響應速度,網頁能再多長時間內打開,通常超過3秒就會感受比較慢了 | 用戶感覺到的時間主要包括網絡通訊、服務器處理、瀏覽器解析時間 |
開發視角 | 主要關注應用程序自己及其子系統的性能 | 例如應用程序自己各業務耗時、併發量、程序是否穩定等 |
運維視角 | 更關注基礎設施性能和資源利用率 | 如運營商帶寬能力,服務器硬件配置,網絡、服務器資源利用率等 |
站在開發、測試人員角度,性能測試的主要指標:響應時間、併發數、吞吐量、服務器各性能指標;算法
性能指標 | 說明 | 測試方法 |
響應時間 | 從發出請求開始到收到最後響應數據所花費的時間 | 通常計算屢次重複請求所花費的總響應時間,再除以請求次數 |
併發數 | 系統可以同時處理請求的數目,也表明了同時發起請求的用戶數 | 多線程模擬併發用戶 |
吞吐量 | 單位時間內系統處理的請求數量,體現出系統的總體處理能力,通常常使用TPS(每秒事務數)、HPS(每秒處理HTTP請求數)、QPS(每秒處理查詢數) | 不斷增長併發數量,查看響應時間的變化曲線 |
服務器各性能指標 | 包括系統負載、內存使用、磁盤使用、CPU使用、網絡I/O等 | 設定閾值,超過閾值報警 |
資源消耗與TPS性能曲線圖:數據庫
併發用戶訪問響應時間曲線圖:後端
根據性能測試,定位產生性能問題的具體緣由,找到瓶頸點,逐步優化;瀏覽器
通常性能優化分爲Web前端性能優化、應用服務器性能優化、存儲服務器性能優化;緩存
優化方法 | 形成性能問題的緣由 | 主要手段 |
減小http請求 | HTTP無狀態,每次請求服務端都須要啓動獨立線程去處理,開銷較大 | 合併CSS、JS文件,合併圖片(可經過CSS偏移來解決顯示問題) |
使用瀏覽器緩存 | 靜態資源更新頻度低,不宜每次都從新獲取 | 設置HTTP頭信息中的Cache-Control和Expires屬性,可設定瀏覽器緩存 |
壓縮 | 靜態資源中一些無用的空格,回車等佔據了大量字節,形成每次網絡傳輸浪費沒必要要的流量 | 可以使用GZip對CSS、JS等文件進行壓縮 |
CSS與JS位置 | 瀏覽器是下載徹底部CSS後纔會對頁面進行渲染,加載JS後則當即執行 | 通常將CSS放在頁面最上面,JS放在頁面底部 |
減小Cookie傳輸 | Cookie會包含在每次的請求和響應中,太大的Cookie會影響數據傳輸 | 儘可能減小Cookie中傳輸的信息量,靜態資源使用獨立的域名訪問,關閉Cookie |
2. CDN加速安全
上面說了,CDN的本質仍然是緩存,將數據緩存在離用戶最近的機房,提高訪問速度,下降中心機房服務器的壓力;
CDN可以緩存的通常都是靜態資源,如圖片,文件,視頻,CSS,JS等,將訪問頻度高的靜態資源放到CDN中;性能優化
反向代理做用 | 說明 |
保護網站安全 | 全部請求到達的第一層都是反向代理服務器,隔離了用戶和網站服務器 |
緩存 | 將靜態資源緩存在反向代理服務器,減輕Web服務器壓力,提高訪問速度 |
負載均衡 | 應用服務器有多臺的話,使用反向代理作負載均衡是不錯的選擇,如Nginx |
網站性能優化第必定律:優先考慮使用緩存優化性能服務器
緩存的本質是內存Hash表,數據以Key/Value的形式存儲在Hash表中,時間複雜度O(1),Hash表存儲以下圖所示:
只要是緩存,就會涉及到緩存未命中與緩存失效問題,所以,緩存中的數據通常都是讀取比例很高,不多變化的數據;
不合理的使用緩存意義不大,還可能下降網站性能,不合理使用緩存可能形成的影響以下表所示:
不合理使用緩存狀況 | 緣由 |
頻繁修改的數據 | 緩存很快會失效,徒增系統負擔 |
沒有熱點的訪問 | 不遵循二八定律,全部數據訪問頻度基本相同的狀況,使用緩存基本沒意義 |
數據不一致與髒讀 | 緩存會設置失效時間,超時後會從新加載,也會形成短期內數據不一致問題,如修改了數據,實時同步緩存,又會形成系統開銷較大問題,須要權衡 |
緩存可用性 | 當緩存大面積失效時或緩存服務崩潰時,會對後端數據庫形成突發性的高併發訪問,瞬間壓力過大,可能致使數據庫服務器宕掉,形成雪崩; 可經過分佈式緩存服務器集羣來提升緩存的可用性; |
緩存穿透 | 不恰當業務或攻擊,持續請求不存在數據,緩存中沒有該數據,全部請求所有落到數據庫服務器上,形成雪崩,可將不存在數據也緩存起來,設爲null來解決此問題; |
分佈式緩存—Memcached,分佈式內存對象緩存系統,K/V存儲,具體流程:
1. 檢查客戶端請求的數據是否在Memchahe中存在,如存在,直接將數據返回; 2. 若是請求數據不在Memcache中,去查詢數據庫,把從數據庫中獲取的數據返回給客戶端,同時把數據緩存到Memcache; 3. 每次更新數據庫,同時更新Memcache中的數據,保證數據一致性; 4. 當分配空間使用完畢後,使用LRU策略替換數據;
Memcached的分佈式算法——一致性哈希,再也不展開討論,比較簡單;
Memcached服務端通訊模塊基於Libevent(支持事件觸發的網絡通訊程序庫),服務器集羣之間互不通訊,能作到線性伸縮;
在高併發下,可以使用負載均衡技術構建應用服務器集羣,將請求分發到多臺應用服務器來處理,下降單臺服務器壓力,提高響應速度;
關注點 | 說明 | 優化 |
多線程 | 多線程優點是充分利用CPU資源,加速請求處理速度; 對於Web應用,用戶請求的多線程一般被Web服務器容器管理; 最需注意的問題:多線程安全 |
最佳線程數: [任務執行時間/(任務執行時間 - IO等待時間)] * CPU核數; 多線程對資源修改必須加鎖 |
資源複用 | 儘可能減小開銷很大的系統資源的建立和銷燬,如數據庫鏈接,網絡通訊鏈接,線程、複雜對象等; | 資源複用主要使用: 1. 單例(如Spring中默認構造的對象都是單例) 2. 對象池(如各類鏈接池,線程池,由於鏈接、線程都是對象,其實各類池都是對象池) |
數據結構 | 好的數據結構和算法的使用是程序性能保障的核心 | —— |
垃圾回收 | 儘可能瞭解所使用語言的垃圾回收算法,瞭解其本質後,在設計程序時能避免一些不良的設計,有助於程序優化和參數調優,編寫內存安全的代碼 | 比較流行的垃圾回收算法主要由引用計數、標記清除以及分代回收等 |
在不少狀況下,磁盤的訪問速度成爲整個系統的瓶頸,並且磁盤中的數據是網站最重要的資產,故磁盤的容錯性和可用性都相當重要;