性能測試是性能優化的前提,也是性能優化結果的檢查和度量標準。舒適提示:本文內容有點長,請耐心看完或者先收藏。前端
①TPS(每秒事務數)web
②HPS(每秒Http請求數)面試
③QPS(每秒查詢數,)算法
減小Http請求的主要手段是合併CSS、合併JS、合併圖片(頁面引用時使用CSS偏移)數據庫
經過設置Http頭中的Cache-Control和Expires的屬性。靜態資源的更新不要直接更新文件內容,要經過更改文件名的方式更新。更新講臺資源的時候使用逐量更新。編程
使用GZIP壓縮,在服務端對文件進行壓縮,在瀏覽器端對文件解壓縮能夠減小通訊傳輸的數據量。可是該種方式會對服務器產生必定的壓力,在款低啊良好而服務器資源不足的狀況下要權衡考慮。後端
瀏覽器會在下載徹底部的CSS以後纔會對頁面進行渲染,因此最好的方式是把CSS放在頁面最上面;可是JS則相反(若是頁面解析時就要用的js仍是要放在最上面)。瀏覽器
好比用戶的登陸信息,能夠考慮使用攔截器,在用戶登陸的時候把登陸信息和用戶的相關信息存放在ThreadLocal裏面。緩存
CDN的本質就是把資源放在離用戶最近的地方,CDN可以緩存的通常是靜態資源,如圖片、文件、CSS、js腳本,靜態網頁。安全
反向代理服務器的兩個用途:
①保護網站安全;
②配置緩存功能能夠加速web請求;
③負載均衡,能夠提升網站的併發數
後臺性能優化的第必定律:優先考慮使用緩存優化性能。
緩存的本質就是一個內存Hash表,數據以一對Key\Value鍵值對存儲在內存Hash表中。主要用戶存放讀寫比很高、不多變化的數據,網站數據一般遵循「二八定律」,即80%的訪問落在20%的數據上,所以,將這20%的數據緩存起來,能夠很好的改善系統性能。
合理的使用緩存對提升系統性能有不少好處,可是不合理的使用緩存反而會成爲系統的累贅甚至風險。濫用緩存的三種狀況以下:
數據的讀寫比至少應該是2:1以上,即寫入一次緩存,在數據更新前至少讀寫兩次,緩存纔有意義。真正實踐中這個比例可能會更高。
若是應用系統訪問數據沒有熱點,不遵循二八定律,即大部分數據訪問並無集中在小部分數據中,那麼緩存也沒有意義,由於大部分數據尚未被再次訪問就已經被擠出緩存了。
寫入緩存的數據最好能容忍必定時間的數據不一致,通常狀況下最好對緩存的數據設置失效時間(固定值+必定範圍的隨機值)。若是不能容忍數據的不一致,必須在數據更新時,刪除對應的緩存(思考:爲何不是更新緩存),可是這種狀況只針對讀寫比很是高的狀況。
緩存雪崩咱們能夠簡單的理解爲:因爲原有緩存失效,新緩存未到期間(例如:咱們設置緩存時採用了相同的過時時間,在同一時刻出現大面積的緩存過時),全部本來應該訪問緩存的請求都去查詢數據庫了,而對數據庫CPU和內存形成巨大壓力,嚴重的會形成數據庫宕機。從而造成一系列連鎖反應,形成整個系統崩潰。
該類問題的解決方式主要有三種:
①加鎖排隊。大概原理是在去數據庫取數據的時候加鎖排隊,該方法僅僅適用於併發量不高的狀況。
②在原有失效時間基礎上加一個合理的隨機值(0-5分鐘)。分佈式場景下最多見的方式(單機也能夠)。
③給緩存加標記,在緩存失效以後更新緩存數據。
緩存穿透是指用戶查詢數據,在數據庫沒有,天然在緩存中也不會有。這樣就致使用戶查詢的時候,在緩存中找不到,每次都要去數據庫再查詢一遍,而後返回空(至關於進行了兩次無用的查詢)。
該類問題的主要解決方式。
①使用布隆過濾器作過濾。該方法僅僅用於查詢一個不可能存在的數據。
②把不存在的數據也緩存起來。最佳實踐:單獨設置比較短的過時時間,好比說五分鐘。
緩存中存放的是熱點數據,熱點數據又是緩存系統利用某種算法對不斷訪問的數據篩選淘汰出來的,在重建緩存數據的過程當中,系統的性能和數據庫負載都不太好,那麼多好的方式就是在緩存系統啓動的時候就把熱點數據加載好,這個緩存預加載的手段叫作緩存預熱。對於一些元數據如省市區列表,類目信息,就能夠在啓動的加載數據庫中的所有數據。
分佈式緩存是指緩存部署在多個服務器組成的集羣中,以集羣方式提供緩存服務,其架構方式有兩種: ①以JBosss Cache爲表明的須要更新同步的分佈式緩存(在全部服務器中保存相同的緩存數據)。 ②以Memcache爲表明的互不通訊的分佈式緩存(應用程序經過一致性Hash等路由算法選擇緩存服務器遠程訪問遠程數據,能夠會容易的擴容,具備良好的可伸縮性)。
使用異步操做,能夠大幅度改善網站的性能,使用異步的兩種場景,高併發、微服務; ①高併發,在不使用消息隊列的狀況下,用戶的請求數據直接寫入數據庫,在高併發的狀況下會對數據庫形成必定的壓力,同時也使得響應延遲加重。使用消息隊列具備很好的削峯做用,在電子商務網站促銷活動中,使用消息隊列是常見的技術手段。 ②微服務之間調用,在微服務流行的當下,有時候咱們調用其餘系統的微服務接口,只是爲了通知其餘系統,咱們不關心結果,這個時候咱們可使用單獨的線程池異步調用其餘系統的微服務,這樣能夠減小程序的響應時間。 任何能夠晚點的事情都應該晚點再作。
在網站高併發訪問的場景洗下,使用負載均衡技術爲一個應用構建一個由多臺服務器組成的服務器集羣,能夠避免單一服務器因負載壓力過大而響應緩慢。經常使用的負載均衡技術有如下幾種:
①HTTP重定向負載均衡,不利於SEO,不推薦。
②DNS域名解析負載均衡,許多DNS服務器還支持基於地理位置的域名解析,會將域名解析成距離用戶地理最近的一個服務器地址,這樣能夠加快訪問速度。大公司經常使用的手段。
③反向代理負載均衡(應用層負載均衡),常見產品:Nginx,反向代理服務器的性能可能會成爲瓶頸。
④IP負載均衡,在內核進程完成數據分發,叫反向代理負載均衡有更好的處理性能,網卡和帶寬會成爲主要的瓶。
⑤數據鏈路層負載均衡(三角傳輸模式),又名DR(直接路由模式),也是大型網站昌運宮的負載均衡手段,在Linux平臺上最好的鏈路層負載均衡產品是LVS。
網站的業務邏輯實現代碼主要部署在應用服務器上,合理的優化代碼也能夠很好的改善網站性能。幾種經常使用的幾種代碼優化方式:
①合理使用多線程,服務器的啓動的線程數參考值:*[任務執行時間/(任務執行時間-IO等待時間)]CPU內核數。
②資源複用,要儘可能減小那些開銷很大的系統資源的建立和銷燬,好比數據庫鏈接,網絡通訊鏈接、線程、複雜對象,從編程角度,資源複用主要有兩種方式,單例、對象池。
③數據結構,前面緩存部分就已經提到了Hash表的基本原理,Hash表的讀寫性能在很大程度上依賴於HashCode的隨機性,即HashCode越散列,Hash表的衝突就越少,目前比較好的Hash散列算法是Time33算法,算法原型爲:hash(i) = hash(i-1)*33+str[i]。
④垃圾回收,好比說在JVM裏,合理設置Young Generation和Old Generation的大小,儘可能減小Full GC,若是設置合理的話,能夠在整個運行期間作到從不進行Full GC。
在網站應用中,海量是的數據讀寫對磁盤訪問會形成必定的壓力,雖然能夠經過Cache解決一部分數據讀壓力,可是不少時候,磁仍然是系統最嚴重的瓶頸。
這兩個的區別我相信你們都知道了吧,機械硬盤是經過馬達驅動磁頭臂帶動磁頭到指定的磁盤位置訪問數據,這個效率我就不用多說了吧,相反,固態硬盤的數據是存儲在能夠持久記憶的硅晶體上,所以能夠像內存同樣隨機訪問,並且功耗更小。
B+樹是一種專門針對磁盤存儲而優化的N叉排序樹,以樹節點爲單位存儲在磁盤中,從根開始查找所需的節點編號和磁盤位置,將其加載到內存中,而後繼續查找,知道找到所需數據,目前大部分關係型數據庫多采用兩級索引的B+樹,樹的層次最多爲3層。
目前不少NoSQL產品採用LSM樹做爲主要的數據結構,LSM樹能夠看作是一個N階合併樹,數據的寫操做都在內存中完成,而且都會建立一個新記錄,這些數據在內存中仍然仍是一顆排序樹。在須要讀的時候,老是從內存中的排序樹開始搜索,若是沒有找到,就從磁盤的排序樹中查找。
在LSM樹上進行一次數據更新不須要磁盤訪問,在內存中便可完成,速度遠快於B+樹,當數據訪問以寫操做爲主,而讀操做則集中在最近寫入的數據上時,使用LSM樹能夠極大程度的減小磁盤的訪問次數,加快訪問速度。
RAID有不少方案,這裏就不細說了,關於RAID的訪問速度、數據可靠性、磁盤利用率見下圖:
在HDFS中,系統在整個存儲集羣的多臺服務器上進行數據的併發讀寫和備份,能夠看作在服務器集羣規模上實現了相似RAID的功能,所以不須要磁盤RAID。
以上就是關於全網最詳細的網站性能(架構)優化手段的所有內容,文章有點長,真的不容易,若是以爲還不錯的話,歡迎轉發、關注。
關注**「Java架構師養成記」,帶你裝逼帶你飛。後臺回覆「面試突擊」**,獲取BAT一線互聯網高頻面試題講解視頻。 歡迎你們關注個人微信公衆號,不按期分享各種面試題。