主頁 > 軟體設計 > 9大性能優化經驗總結,強烈建議收藏!

9大性能優化經驗總結,強烈建議收藏!

2022-08-17 12:05:16 軟體設計

性能優化屬于Java高級崗的必備技能,而且大廠特別喜歡考察,今天主要給大家介紹9種性能優化的方法@mikechen

1.代碼

之所以把代碼放到第一位,是因為這一點最容易引忽視,比如拿到一個性能優化的需求以后,言必稱快取、異步等,

實際上,第一步就應該是分析相關的代碼,找出相應的瓶頸,再來考慮具體的優化策略,

有一些性能問題,完全是由于代碼寫的不合理,通過直接修改一下代碼就能解決問題的,比如for回圈次數過多、作了很多無謂的條件判斷、相同邏輯重復多次等,這樣的優化成本是最低的,

 

2.資料庫

1.SQL優化

這里以MySQL為例,最常見的方式是,由自帶的慢查詢日志或者開源的慢查詢系統定位到具體的出問題的SQL,然后使用explain、profile等工具來逐步調優,最后經過測驗達到效果后上線,

這里舉幾個優化的例子:

1.查詢優化

對查詢進行優化,要盡量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引,

2.避免null判斷

應盡量避免在 where 子句中對欄位進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如:

select id from t where num is null

3.避免全表掃描

應盡量避免在 where 子句中使用 != 或 <> 運算子,否則將引擎放棄使用索引而進行全表掃描,

應盡量避免在 where 子句中使用 or 來連接條件,如果一個欄位有索引,一個欄位沒有索引,將導致引擎放棄使用索引而進行全表掃描,

in和 not in 也要慎用,否則會導致全表掃描,如:

select id from t where num in(1,2,3)

對于連續的數值,能用 between就不要用 in 了:

select id from t where num between 1 and 3

4.大資料量查詢

對于多張大資料量的表JOIN,要先分頁再JOIN,否則邏輯讀會很高,

5.合理使用索引

索引并不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率,因為 insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定,

一個表的索引數最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有 必要,

6.多使用數字型欄位

盡量使用數字型欄位,若只含數值資訊的欄位盡量不要設計為字符型,這會降低查詢和連接的性能,并會增加存盤開銷,

這是因為引擎在處理查詢和連 接時會逐個比較字串中每一個字符,而對于數字型而言只需要比較一次就夠了,

7.避免大數量

盡量避免向客戶端回傳大資料量,若資料量過大,應該考慮相應需求是否合理,

8.避免大事務

盡量避免大事務操作,提高系統并發能力,

 

2.連接池調優

我們的應用為了實作資料庫連接的高效獲取、對資料庫連接的限流等目的,通常會采用連接池類的方案,即每一個應用節點都管理了一個到各個資料庫的連接池,

隨著業務訪問量或者資料量的增長,原有的連接池引數可能不能很好地滿足需求,這個時候就需要結合當前使用連接池的原理、具體的連接池監控資料和當前的業務量作一個綜合的判斷,通過反復的幾次除錯得到最終的調優引數,

更加全面深入的MySQL性能優化,請查看《MySQL慢查詢優化、索引優化、以及表等優化總結》,

 

3.架構層面

這一類調優包括讀寫分離、多從庫負載均衡、水平和垂直分庫分表等方面,一般需要的改動較大,但是頻率沒有SQL調優高,而且一般需要DBA來配合參與,

詳細的分庫分表、讀寫分離,請查看《資料庫分庫分表、讀寫分離的原理實作,使用場景》

 

3.分布式快取

快取可以稱的上是性能優化的利器,快取主要用來存放那些讀寫比很高、很少變化的資料,

什么情況適合用快取?考慮以下兩種場景:

  •  短時間內相同資料重復查詢多次且資料更新不頻繁,這個時候可以選擇先從快取查詢,查詢不到再從資料庫加載并回設到快取的方式,此種場景較適合用單機快取,
  •  高并發查詢熱點資料,后端資料庫不堪重負,可以用快取來扛,

使用快取需要注意的問題:

1.避免快取失效

把頻繁修改的資料放入快取,容易出現資料寫入快取后,應用還來不及讀取快取,資料就已經失效的情形,徒增系統負擔,

2.快取熱點資料

快取使用的記憶體資源非常寶貴,只能將最新訪問的資料快取起來,而把歷史資料清理出快取,即快取資源應該留給20%的熱點資料,

 3.資料不一致性

一般會對快取設定失效時間,超過失效時間,就要從資料庫重新加載,

因此應用要忍受一定時間的資料不一致,另一種策略是資料更新時立即更新快取,不過這也會帶來更多的系統開銷和事務一致性的問題,

 4.快取可用性

業務發展到一定階段時,快取會承擔大部分資料訪問的壓力,資料庫已經習慣了有快取的日子,所以當快取服務器崩潰時,資料庫會因為完全不能承受如此大的壓力而宕機,進而導致整個網站不可用,這種情況被稱作快取雪崩,發生這種故障,甚至不能簡單地重啟快取服務器和資料庫服務器來恢復網站訪問,

解決方式:

1)快取熱備(當某臺服務器宕機時,將快取訪問切換到熱備服務器上;

2)快取服務器集群,

5. 快取預熱

快取中存放的是熱點資料,熱點資料是快取系統用LRU對不斷訪問的資料篩選出來的,這個程序需要較長的時間,

新啟動的快取系統沒有任何資料,此時系統的性能和資料庫負載都不太好,因此可以選擇在啟動快取是就把熱點資料預加載好,

 6.快取穿透

因為不恰當的業務或惡意攻擊,持續高并發地訪問某一個不存在的資料,如果快取不保存該資料,就會有大量的請求壓力落在資料庫上,

簡單的解決方式是把請求的不存在的資料也放進快取,其value是null,

如果還想全面了解快取的5大難題,《如何解決Redis快取雪崩、快取穿透、快取并發等5大難題》有更加深入全面的講解,

 

4.異步化

針對某些客戶端的請求,在服務端可能需要針對這些請求做一些附屬的事情,這些事情其實用戶并不關心或者用戶不需要立即拿到這些事情的處理結果,這種情況就比較適合用異步的方式處理這些事情,

異步化的作用:

  •  縮短介面回應時間,使用戶的請求快速回傳,用戶體驗更好,
  •  避免執行緒長時間處于運行狀態,這樣會引起服務執行緒池的可用執行緒長時間不夠用,進而引起執行緒池任務佇列長度增大,從而阻塞更多請求任務,使得更多請求得不到技術處理,
  •  執行緒長時間處于運行狀態,可能還會引起系統Load、CPU使用率、機器整體性能下降等一系列問題,甚至引發雪崩,異步的思路可以在不增加機器數和CPU數的情況下,有效解決這個問題,

比如:使用訊息佇列(MQ)中間件服務,MQ天生就是異步的,

一些額外的任務,可能不需要我這個系統來處理,但是需要其他系統來處理,這個時候可以先把它封裝成一個訊息,扔到訊息佇列里面,通過訊息中間件的可靠性保證把訊息投遞到關心它的系統,然后讓這個系統來做相應的處理,

再比如C端在完成一個提單動作以后,可能需要其它端做一系列的事情,但是這些事情的結果不會立刻對C端用戶產生影響,那么就可以先把C端下單的請求回應先回傳給用戶,回傳之前往MQ中發一個訊息即可,而且這些事情理應不是C端的負責范圍,所以這個時候用MQ的方式,來解決這個問題最合適,

 

5.Web前段

Web前端指網站業務邏輯之前的部分,包括:

  • 瀏覽器加載
  • 網站視圖模型
  • 圖片服務
  • CDN服務等

主要優化手段有優化瀏覽器訪問,使用反向代理,CDN等,

1.瀏覽器訪問優化

(1)減少http請求

HTTP協議是無狀態的應用層協議,意味著每次HTTP請求都需要簡歷通信鏈路,進行資料傳輸,而在服務器端,每個HTTP都需要啟動獨立的執行緒去處理,這些通信和服務的開銷都很昂貴,減少HTTP請求的數目可有效提高訪問性能,

減少HTTP請求的主要手段是:

  •  合并CSS,以及壓縮CSS大小
  •  合并JavaScript,以及壓縮JS大小
  •  合并圖片

將瀏覽器一次訪問需要的JavaScript,CSS合并成一個檔案,這樣瀏覽器就只需要一次請求,多張圖片合并成一張,如果每張圖片都有不同的超鏈接,可通過CSS偏移回應滑鼠點擊操作,構造不同的URL,

(2)使用瀏覽器快取

對一個網站而言,CSS,JavaScript,Logo,圖示等這些靜態資源檔案更新的頻率都比較低,而這些檔案又幾乎是每次HTTP請求都需要的,如果將這些檔案快取在瀏覽器中,可以極好地改善性能,通過設定HTTP頭中Cache-Control和Expires屬性,可設定瀏覽器快取,快取時間可以是數天甚至是幾個月,有時候,靜態資源檔案變化需要及時應用到客戶端瀏覽器,這種情況可以通過改變檔案名實作,比如一般會在JavaScript后面加上一個版本號,使瀏覽器重繪修改的檔案,

(3)啟用壓縮

在服務器端對檔案進行壓縮,在瀏覽器端對檔案解壓縮,可有效較少通信傳輸的資料量,文本檔案的壓縮效率科大80%以上,

(4)CSS放在頁面最上面,JavaScript放在頁面最下面

瀏覽器會在下載完全部CSS之后對整個頁面進行渲染,因此最好的做法是將CSS放在頁面最上面,讓瀏覽器盡快下載CSS,JS則想法,瀏覽器在加載JS后立即執行,有可能會阻塞整個頁面,造成頁面顯示緩慢,因此JS最好放在頁面最下面,

(5)減少Cookie傳輸

一方面,Cookie包含在每次請求和回應中,太大的Cookie會嚴重影響資料傳輸,因此哪些資料需要寫入Cookie需要慎重考慮,盡量減少Cookie中傳輸的資料量,另一方面,對于某些靜態資源的訪問,如CSS,JS等,發送Cookie沒有意義,可以考慮靜態資源使用獨立域名訪問,避免請求靜態資源時發送Cookie,減少Cookie傳輸的次數,

2.CDN加速

CDN(Content Distribute Network,記憶體分發網路)的本質上仍然是一個快取,而且將資料快取在離用戶最近的地方,是用戶以最快速度獲取資料,即所謂網路訪問第一跳,

CDN一般快取的是靜態資源,如圖片,檔案,CSS,Script腳本,靜態網頁等,但是這些檔案訪問頻率很高,將其快取在CDN可極大改善網頁的打開速度,

3.反向代理

傳統代理服務器位于瀏覽器一側,代理瀏覽器將HTTP請求發送到互聯網上,而反向代理服務器位于網站機房一側,代理網站Web服務器接收HTTP請求,

和傳統代理服務器可以保護瀏覽器安全一樣,反向代理服務器也具有保護網站安全的作用,來自互聯網的訪問請求必須經過代理服務器,相當于在Web服務器和可能的網路攻擊之間建立了一個屏障,

除了安全功能,代理服務器也可以通過配置快取功能加速Web請求,當用戶第一次訪問靜態內容的時候,靜態內容就被快取在反向代理服務器上,這樣當其他用戶訪問該靜態內容的時候,就可以直接從反向代理服務器回傳,加速Web請求回應速度,減輕服務器負載要,

 

6.服務化

做服務化最基礎的是按業務做服務拆分,避免跨業務間的互相影響,資料和服務同時拆分,同一個業務內部我們還按計算密集型/IO密集型的服務拆分、C端/B端服務拆分、核心/非核心服務拆分、高頻服務單獨部署等原則做拆分,

 

7.硬體升級

硬體問題對性能的影響不容忽視,

舉一個例子:一個DB集群經常有慢SQL報警,業務排查下來發現SQL都很簡單,該做的索引優化也都做了,后來DBA同學幫忙定位到問題是硬體過舊導致,將機械硬碟升級成固態硬碟之后報警立馬消失了,效果立竿見影!

 

8.搜索引擎

復雜查詢以及一些聚合計算不適合在資料庫中做,可以利用搜索引擎來實作,另外搜索引擎還可以幫我們很好的解決跨庫、跨資料源檢索的場景,

 

9.產品邏輯優化

業務邏輯優化經常會容易被忽略,但效果卻往往比資料庫性能優化、JVM調優之類的來的更明顯,

舉一個例子,12306春運搶火車票的場景,由于訪問的人多,用戶點擊“查票”之后系統會非常卡,進度條非常慢,作為用戶,我們會習慣性的再去點“查票”,可能會連續點個好幾次,

假設平均一個用戶點5次,則后端系統負載就增加了5倍!而其中80%的請求是重復請求,

這個時候我們可以通過產品邏輯的方式來優化,比如,在用戶點擊查詢之后將“按鈕置灰”,或者通過JS控制xx秒只能只能提交一次請求等,有效的攔截了80%的無效流量,

 

以上

作者簡介

陳睿|mikechen,10年+大廠架構經驗,《BAT架構技術500期》系列文章作者,分享十余年BAT架構經驗以及面試心得!

閱讀mikechen的互聯網架構更多技術文章合集

Java并發|JVM|MySQL|Spring|Redis|分布式|高并發|架構師

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/502038.html

標籤:架構設計

上一篇:企業應用架構研究系列二十三:微服務之程式網關YARP

下一篇:設計模式——創建型設計模式

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more