程式員必須練就的「性能調優」組合拳【3】

来源:https://www.cnblogs.com/itlaobingge/archive/2020/01/20/12216857.html
-Advertisement-
Play Games

Y 維度就是從業務 HTTP 請求的橫向處理流程來看,HTTP 請求會穿越網路、電腦、應用容器(Tomcat)、Spring、ORM(Hibernate)、資料庫等節點,在這個流程中每個節點都有許多可以可優化的地方,今天老兵哥將介紹通過優化開發框架 Spring 來優化系統性能的方法。 ...


性能調優系列前序文章索引:

  • 程式員必須掌握的性能調優老兵哥結合個人經歷解釋了程式員往架構師方向發展時為什麼要跨越性能調優這一關,以及介紹了從 X、Y、Z 三個維度優化性能的思路。
  • 從  X  維度優化系統的性能老兵哥分享了從 X 維度優化系統性能的思路,包括讓客戶端分計算存儲任務、優化交互設計等,主要是作為引子拓寬我們性能調優的思路。
  • 應用容器 Tomcat 性能調優Y 維度就是從業務 HTTP 請求的橫向處理流程來看,HTTP 請求會穿越網路、電腦、應用容器(Tomcat)、Spring、ORM(Hibernate)、資料庫等節點,在這個流程中每個節點都有許多可以可優化的地方,此文主要介紹通過優化應用容器(Tomcat)來優化系統性能的方法。

程式員在轉型架構師的過程中需要建立流程化、結構化、系統化的思維方式,而性能調優是非常難得的契機,它既給了我們壓力,也給了我們動力,跨越它就是突破自己的過程。

  • X 維度,即業務維度,技術始終是服務業務的,任何技術問題的原點就是業務需求。在啟動技術層面的性能優化之前,我們有必要先審視一下業務流程是否合理,交互設計上有沒有可以優化的空間等。
  • Y 維度,待業務維度優化完畢,接下來就是審視技術在實現當前業務流程或交互設計的全鏈路上有沒有可優化的地方,即 HTTP 請求處理全流程,從瀏覽器到應用容器,再到 Spring、Hibernate、資料庫等。
  • Z 維度,除了沿著 HTTP 請求的橫向鏈路,我們還要審視支持應用系統的縱向技術棧,從上到下包括 JVM、操作系統和硬體等,這是整套應用系統運行的環境,許多性能問題都跟運行環境存在關係。

今天老兵哥將介紹通過優化開發框架 Spring 來優化系統性能的方法。

3. 開發框架 Spring

3.1 事務管理

事務(Transaction),是併發控制的基本單位,是用戶定義的一個操作序列。這些操作要麼都做,要麼都不做,是一個不可分割的工作單位。通過使用事務控制,我們可以極大地避免邏輯處理失敗導致的臟數據等問題。事務具有 4 個屬性:原子性、一致性、隔離性、持久性等,這四個屬性通常稱為 ACID 特性。

  • 原子性(Atomicity),一個事務是一個不可分割的工作單位,事務包含的操作要麼都做、要麼都不做。
  • 一致性(Consistency),事務必須讓資料庫從一個一致性狀態變到另一個一致性狀態,不能出現不一致。
  • 隔離性(Isolation),一個事務的執行不能被其他事務干擾,即一個事務內部的操作及使用的數據對併發的其他事務是隔離的,併發執行的各個事務之間不能互相干擾。
  • 持久性(Durability),持久性也稱永久性,指一個事務一旦提交,它對資料庫中數據的改變是永久性的,接下來的其他操作或故障不應該對其有任何影響。

Spring 事務管理是通過 XML 文件或註解 @Transactional 配置的,其背後是靜態代理或動態代理等技術。在代理模式下,那些從代理傳遞傳過來的“外部”方法調用會被攔截,但“自我調用”是不會觸發事務的。例如,在目標對象中調用自身其他方法的方法是不會觸發事務的,即使被調用的方法標記為 @Transactional。

通常,我們很少關註 Spring 事務管理相關的屬性,但這些屬性的取值會影響系統的性能。Spring 事務管理最重要的兩個特性是:傳播級別、隔離級別。傳播級別,定義了事務的控制範圍;隔離級別,定義了事務在資料庫讀寫方面的控制範圍。我們知道,事務的控制範圍越大,系統的併發性就會越差,性能也就隨之降低。事務的隔離級別越高,系統的併發性也會越差,性能也會隨之下降。如果不瞭解這些屬性的取值規則,我們就不能選擇最合適的取值,不知不覺中就會浪費許多系統資源,接下來我們一起來看看這些屬性。

屬性類型描述
propagation 枚舉型:Propagation 傳播級別,可選,預設值:PROPAGATION_REQUIRED
isolation 枚舉型:Isolation 隔離級別,可選,預設值:ISOLATION_DEFAULT
readOnly 布爾型 讀寫型事務、只讀型事務
timeout INT 型,以秒為單位 事務超時閾值
rollbackFor 一組 Class 類,必須是 Throwable 的子類 一組異常類,遇到時必須回滾。預設情況下 Checked Exceptions 不進行回滾,僅 Unchecked Exceptions(即 RuntimeException 的子類)才進行事務回滾。
rollbackForClassname 一組 Class 類的名字,必須是 Throwable 的子類 一組異常類名,遇到時必須回滾
noRollbackFor 一組 Class 類,必須是 Throwable 的子類 一組異常類,遇到時不需要回滾

Spring 事務管理的傳播級別 Propagation 取值有以下幾種: 

傳播級別說明備註
PROPAGATION_REQUIRED 如果上下文中已經存在事務,那麼就加入到事務中執行;如果上下文中不存在事務,則新建事務執行。 這個級別通常能滿足處理大多數的業務場景。
PROPAGATION_SUPPORTS 如果上下文中已經存在事務,則支持加入到事務中執行;如果上下文中不存在事務,則使用非事務的方式執行。 這個通常是用來處理那些並非原子性的非核心業務邏輯操作,應用場景較少。
PROPAGATION_MANDATORY 該級別的事務要求上下文中必須要存在事務,否則就會拋出異常。這是避免上下文調用代碼遺漏添加事務控制的保證手段。 例如某段代碼不能被單獨調用執行,但是一旦被調用就必須要有事務包含,這種情況下就可以使用這個傳播級別。
PROPAGATION_REQUIRES_NEW 每次都會新建一個事務,並且同時將上下文中的事務掛起,執行當前新建事務完成以後,上下文事務恢復再執行。 問題1:如果某個子事務發生回滾,父事務是否回滾?答案是不會,因為子事務是新建事務,父事務已經被掛起,兩者不會受到影響。問題2:如果父事務發生回滾,子事務是否回滾?答案是不會,同樣的理由。但是可以手動控制,一旦子事務回滾,父事務也回滾。
PROPAGATION_NOT_SUPPORTED 如果上下文中已經存在事務,則掛起事務,執行當前邏輯,結束後恢覆上下文的事務。 這個級別可以幫助你儘可能地縮小事務範圍。一個事務範圍越大,它存在的風險也就越多,例如某段代碼是迴圈 1000 次的非核心業務邏輯操作,此類代碼如果包在事務中,勢必導致事務太大,很容易出現些難以考慮周全的異常情況,此時這個級別就派上用場了。
PROPAGATION_NEVER 該級別要求上下文中不能存在事務,一旦有事務,就拋出runtime異常,強制停止執行。

 傳播級別 PROPAGATION_REQUIRED 會為每一個被應用到的方法創建一個邏輯事務作用域。每一個邏輯事務作用域都可以自主地決定回滾條件,當這樣的邏輯事務作用域被外部邏輯事務作用域所包含時,它們在邏輯上是獨立的,但在實現層面它們會被映射到相同的物理事務上。

傳播級別 PROPAGATION_REQUIRES_NEW 為每一個相關的事務作用域使用了一個完全獨立的事務。在這種情況下,物理事務也將是不同的。因此,外部事務可以不受內部事務回滾狀態的影響獨立提交或者回滾。

Spring 事務管理的隔離級別 Isolation 取值有以下幾種:

隔離級別說明
Serializable 最嚴格的級別,事務串列執行,資源消耗最大。
Repeatable Read 保證了一個事務不會修改已經由另一個事務讀取但未提交(或回滾)的數據,避免了“臟讀取”和“不可重覆讀取”的情況,但會帶來了更多的性能損耗。
Read Committed 大多數主流資料庫的預設事務等級,保證了一個事務不會讀到另一個並行事務已修改但未提交的數據,避免了“臟讀取”,該級別適用於大多數系統。
Read Uncommitted 保證了讀取過程中不會讀取到非法數據。

上述說明中涉及的幾個專業術語:

  • 臟讀(Dirty Reads):就是讀到了別的事務回滾前的臟數據。例如,事務 B 執行過程中修改了數據 X,在未提交前,事務 A 讀取了 X,而事務 B 卻回滾了,這樣事務 A 就形成了臟讀。
  • 不可重覆讀(Non-Repeatable Reads):不可重覆讀字面含義已經很明確了。例如,事務 A 首先讀取了一條數據,然後執行邏輯的時候,事務 B 將這條數據改變了,然後事務 A 再次讀取的時候,發現數據不匹配了,這就是所謂的不可重覆讀。
  • 幻讀(Phantom Reads):我們小時候數鴨子,第一次數是 10 個,第二次數是 11 個,怎麼回事,產生幻覺了?幻讀也是這樣子,事務 A 先根據條件索引到 10 條數據,然後事務 B 改變了資料庫一條數據,導致也符合事務 A 的搜索條件,這樣事務 A 再次搜索發現有 11 條數據了,這就產生了幻讀。
隔離級別與副作用臟讀不可重覆讀幻讀
Serializable 不會 不會 不會
Repeatable Read 不會 不會
Read Committed 不會
Read Uncommitted

從上面這張映射表中,我們知道最安全的是 Serializable,但是伴隨而來的是高昂的性能開銷。各種傳播級別、隔離級別本身沒有好壞,關鍵是根據業務需求選擇最合適的取值,避免無效的性能損耗。另外,Spring 事務管理還有兩個常用屬性,它們的取值也會影響性能:

  • Readonly:只讀型事務要比讀寫型事務的性能更好,設置事務為只讀以提升性能。
  • Timeout:設置事務的超時時間,一般用於防止大事務的發生,事務要儘可能的小。

3.2 二級緩存

緩存作為提高應用系統性能的一種有效途徑,在事務管理配置不當的情況下,將很難發揮應有的效用。因此,在做緩存處理或者其他處理,要考慮事務管理對性能的影響。

 

關註「 IT老兵哥 」,賦能程式人生!堅持原創不易,請小伙伴們不吝點個「  」哦!推薦軟技能文章,請點擊鏈接:程式員,怎樣打造個人影響力?

 

 

近期熱評系列《 程式員必須懂的架構師入門課 》:


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 圓角矩形介紹 在 中通過 屬性可以實現元素的圓角矩形。 屬性值一共有 個,左上、右上、左下、右下。 屬性值規則如下:第一個值為左上、第二個值為右上、第三個值為左下、第四個值為右下。 假如 屬性值都是一致的我可以設置一個屬性值即可。 圓角矩形實踐 圓角矩形基本使用方式 如果我們的 屬性值一致實踐。 如 ...
  • 起步 下載模板: 初始化項目: 將 文件內容替換如下: 安裝模板依賴的樣式文件: 在 文件中導入樣式文件: 看到如下頁面說明成功。 ...
  • todolist小案例 "該案例的模板文件下載地址" 走外國伺服器, ̄□ ̄|| app.module.ts 核心組件app.component.ts 發現這倆不是同一類文件,哈哈哈,٩(๑ ◡ !t.done) } else if (this.visibility === 'completed') ...
  • Node.js簡介 Node.js是一個能夠在伺服器端運行JavaScript的開源代碼、跨平臺JavaScript運行環境 Node採用Google開發的V8引擎運行js代碼,使用事件驅動、非阻塞和非同步I/O模型等技術來提高性能,可優化應用程式的傳輸量和規模 Node大部分基本模塊都用JavaSp ...
  • 前言 最近在學習研究 Nest 框架,但是在學習過程中除了參考翻閱官方文檔外國內幾乎沒有多少資料能系統的講解 Nest 的相關內容,所以打算想通過我自己學習的角度講解下 Nest 框架,不知道能堅持多久,也可能有錯誤或遺漏的地方,歡迎大家批評指正。 下麵我學習 Nest 的主要信息來源,在編寫過程中 ...
  • 7)onloadonload就是等頁面載入完後才執行。例 3.7.1<HEAD> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <SCRIPT LANGUAGE="JavaScript"> <!-- func ...
  • Vue開發環境跨域訪問其他伺服器或者本機其他埠,需要配置項目中config/index.js文件,修改如下 module.exports = { dev: { // Paths assetsSubDirectory: 'static', assetsPublicPath: '/', proxyTa ...
  • 程式員在轉型架構師的過程中需要建立流程化、結構化、系統化的思維方式,而性能調優是非常難得的契機,它既給了我們壓力,也給了我們動力,跨越它就是突破自己的過程。Y 維度,就是從業務 HTTP 請求的橫向處理流程來看,HTTP 請求會穿越網路、電腦、應用容器(Tomcat)、Spring、ORM(Hib... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...