性能調優,程式員轉型架構師的攔路虎【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
更多相關文章
  • 針對近日華為,小米的部分機型,在升級系統或升級微信之後,微信內置瀏覽器產生的rem不能正確填充滿的問題,有如下解決方案 目前來看,產生這個情況的原因是因為給html附font-size時,附上的font-size和實際上html的font-size 大小並不一致 如圖: 在問題機型上展示的三個值 分 ...
  • 彈出輸入框會使視口高度發生變化,彈出輸入框後動態匹配這個高度 以下是使用jq的方法 $('input').on('blur', function () { setTimeout(function () { var scrollHeight = document.documentElement.scr ...
  • 問題1: 通過document.addEventListener("scroll",function(){})對頁面滾動監聽事件進行監聽,但ios下$(document).scrollTop()值始終為0,對頁面監聽無效。 原因: 因為iOS下iframe的高度會根據頁面的內容自適應,造成了ifra ...
  • Title: Why you should use Object.is() in equality comparison Author: TarekAlQaddy Website: https://www.jstips.co/en/javascript/why-you-should-use-Obje ...
  • 一曲肝腸斷 ,天涯何處覓知音。 借用星爺電影的一句臺詞作為開篇,形容下自己的心境,年終將至,迴首2019,也不算太虧欠自己,明年繼續努力生長。 這是自己第一次在博客介紹自己,目前坐標長沙,三流大專,市場營銷專業,是的,毫不相干的專業,也讓我在轉行前端途中吃了比一般人多一點的苦頭,為什麼轉行呢,自然是 ...
  • 基於個人的經驗,談談設計模式在網關中的應用。因為是經驗之談,沒有絕對的對與錯。 下麵整理的是我最常使用的設計模式,我用設計模式的前提是 讓代碼的可讀性變強 能支持日後功能擴展 單例 目的 保證全局只有一個實例,防止因為頻繁的創建、銷毀對象而造成不必要的性能開銷。 在網關項目中,單例模式是出現頻率最高 ...
  • 無論哪種類型的Web API, 都可能需要給其他開發者使用. 所以API的開發者體驗是很重要的. API的開發者體驗, 簡寫為 API DX (Developer Experience). 它包含很多東西, 例如如何使用API, 文檔, 技術支持等等, 但是最重要的還是API的設計. 如果 API ...
  • [TOC] 前言 開發環境 部署環境:阿裡雲ECS伺服器 操作系統:CentOS 7.7 64位 IDEA 版本:2019.3.1 docker 版本:1.13.1 docker compose版本:1.25.0 spring cloud 版本:Hoxton.SR1 spring boot 版本:2 ...
一周排行
    -Advertisement-
    Play Games
  • GoF之工廠模式 @目錄GoF之工廠模式每博一文案1. 簡單說明“23種設計模式”1.2 介紹工廠模式的三種形態1.3 簡單工廠模式(靜態工廠模式)1.3.1 簡單工廠模式的優缺點:1.4 工廠方法模式1.4.1 工廠方法模式的優缺點:1.5 抽象工廠模式1.6 抽象工廠模式的優缺點:2. 總結:3 ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...