當前位置:遊戲中心平台 - 頁遊排行榜 - 求助,如何處理分布式事務?

求助,如何處理分布式事務?

1.性能和延遲問題在服務之前,業務通常由本地API調用,本地方法調用的性能損失較小。服務後,服務提供者和消費者之間采用遠程網絡通信,增加了額外的性能損失:1)客戶端需要序列化消息,主要占用CPU計算資源。2)序列化過程中需要創建二進制數組,這會消耗JVM堆內存或堆外內存。3)客戶端需要向服務器發送序列化的二進制數組,占用網絡帶寬資源。4)服務器讀取碼流後,需要將請求數據報反序列化為請求對象,占用CPU計算資源。5)服務器調用服務提供者通過反射實現類,反射本身對性能影響很大。6)服務器序列化響應結果,占用CPU計算資源。7)服務器向客戶端發送響應碼流,占用網絡帶寬資源。8)客戶端讀取響應碼流,反序列化成響應消息,占用CPU資源。通過分析我們發現,壹個簡單的本地方法調用,切換到遠程服務調用後,增加了很多額外的處理流程,不僅占用了大量的系統資源,還增加了延遲。壹些復雜的應用會被拆分成多個服務,形成壹個服務調用鏈。如果服務框架性能差,服務調用延遲長,那麽服務後的性能和延遲就達不到業務的性能要求。在1.1 RPC框架的高性能設計中,影響RPC框架性能的因素主要有三個。1)I/O調度模型:同步阻塞I/O(BIO)或非阻塞I/O(NIO)。2)序列化框架的選擇:文本協議、二進制協議或壓縮二進制協議。3)線程調度模型:串行調度還是並行調度,鎖爭用還是無鎖算法。1.I/O調度模型在I/O編程過程中,當需要同時處理多個客戶端訪問請求時,可以采用多線程或者I/O復用技術進行處理。I/O復用技術將多個I/O的阻塞復用到同壹個select的阻塞上,使得系統在單線程的情況下可以同時處理多個客戶端請求。與傳統的多線程/多進程模型相比,I/O復用最大的優點是系統開銷小,系統不需要創建新的額外進程或線程,也不需要維護這些進程和線程的運行,減少了系統的維護工作量,節省了系統資源。JDK1.5_update10使用epoll代替傳統的select/poll,大大提高了NIO通信的性能。其工作原理如圖1-1所示。圖1-1非阻塞I/O工作原理Netty是壹個開源的高性能NIO通信框架:其I/O線程NioEventLoop因為聚合了多路選擇器,所以可以同時處理數百個客戶端通道。由於讀寫操作是非阻塞的,這樣可以充分提高I/O線程的運行效率,避免頻繁I/O阻塞導致的線程掛起。此外,由於Netty采用異步通信方式,壹個I/O線程可以並發處理N個客戶端連接和讀寫操作,從根本上解決了傳統的同步阻塞I/O-connection-thread模型,架構的性能、靈活性和可靠性都有了很大的提高。Netty經過精心設計,提供了許多獨特的性能提升特性,這使得它在各種NIO框架中排名第壹。其性能優化措施總結如下。1)零拷貝:(1)Netty的接收和發送字節緩沖區采用DIRECTBUFFERS,堆外直接內存用於Socket讀寫,不需要對字節緩沖區進行二次拷貝。如果使用傳統的堆緩沖區進行套接字讀寫,JVM會在將堆緩沖區寫入套接字之前將它的副本復制到直接內存中。與堆外直接內存相比,消息在發送過程中多了壹個緩沖區的內存副本。(2)Netty提供了壹個組合的Buffer對象,可以聚合多個ByteBuffer對象。用戶可以像操作壹個緩沖區壹樣輕松地操作組合緩沖區,避免了傳統的通過內存復制將幾個小緩沖區合並成壹個大緩沖區的方式。(3)Netty的文件傳輸采用transferTo方法,可以直接將文件緩沖區中的數據發送到目標通道,避免了傳統循環寫方法帶來的內存復制問題。2)內存池:隨著JVM虛擬機和JIT即時編譯技術的發展,對象的分配和回收是壹項非常輕量級的工作。但是對於Buffer來說,情況略有不同,尤其是對於堆外直接內存的分配和回收,這是壹個非常耗時的操作。為了盡可能地重用緩沖區,Netty提供了壹種基於內存池的緩沖區重用機制。性能測試顯示,帶內存池的ByteBuf性能比不斷死亡的ByteBuf高23倍左右(性能數據與使用場景強相關)。3)無鎖串行設計:在大多數場景下,並行多線程可以提高系統的並發性能。但如果對* * *資源的並發訪問處理不當,會帶來嚴重的鎖競爭,最終導致性能下降。為了盡可能避免鎖競爭帶來的性能損失,可以采用序列化設計,即消息處理盡可能在同壹個線程中完成,在此期間不進行線程切換,從而避免多線程競爭和同步鎖。為了盡可能提高性能,Netty采用了串行無鎖設計,在I/O線程內進行串行操作,避免多線程競爭導致的性能下降。表面上看,序列化設計似乎CPU利用率低,並發不足。然而,通過調整NIO線程池的線程參數,可以同時啟動多個序列化線程並行運行,這種部分解鎖的串行線程設計比壹個隊列多工作線程模型具有更好的性能。4)高效並發編程:海量、正確使用volatileCAS和原子類的廣泛使用;線程安全容器的使用;通過讀寫鎖來提高並發性能。2.影響高性能序列化框架的序列化性能的關鍵因素總結如下。1)序列化碼流大小(網絡帶寬占用)。2)序列化&;反序列化的性能(CPU資源使用)。3)是否支持跨語言(異構系統的對接和開發語言的切換)。4)並發調用的性能:穩定性、線性增長、偶爾的延遲毛刺等。與JSON等文本協議相比,二進制序列化框架的性能更好。以Java原生序列化和Protobuf二進制序列化為例,進行性能測試對比,結果如圖1-2所示。圖1-2序列化性能測試對比數據在序列化框架的技術選擇上,如果沒有特殊要求,盡量選擇性能更好的二進制序列化框架。碼流是否壓縮,需要根據通信內容靈活選擇。對於有大量重復內容的圖片、音頻和文本文件(如小說),可以采用碼流壓縮。常見的壓縮算法包括GZip、Zig-Zag等。3.高性能反應器線程模型該模型的特征總結如下。1)有壹個特殊的NIO線程:Acceptor線程用於監控服務器,接收客戶端的TCP連接請求。2)網絡I/O操作:讀寫由壹個NIO線程池處理,可以通過標準的JDK線程池實現。它包含壹個任務隊列和n個可用線程,這些NIO線程負責讀取、解碼、編碼和發送消息。3)1個NIO線程可以同時處理n個鏈接,但是1個鏈接只對應1個NIO線程,防止並發操作。因為反應器模式使用異步非阻塞I/O,所以所有I/O操作都不會導致阻塞。理論上,壹個線程可以獨立處理所有I/O相關的操作,因此在大多數場景下,Reactor多線程模型完全可以滿足業務性能需求。反應器線程調度模型的工作原理如圖1-3所示。圖1-3高性能反應器線程調度模型1.2業務最佳實踐要保證高性能,僅僅依靠分布式服務框架是不夠的,還需要應用程序的配合。應用服務的高性能實踐總結如下:1)異步或並行服務調用盡量異步使用,可以提高服務吞吐量,有效降低服務調用延遲。2)無論是NIO通信框架的線程池,還是後端業務線程池,線程參數的配置都必須合理。如果采用默認的JDK線程池,建議最大線程數不超過20。因為JDK的線程池默認采用n個線程爭用1個同步阻塞隊列的模式,當線程數量過多時,會導致激烈的鎖競爭,性能不但不會提高,反而會下降。3)最小化要傳輸的碼流大小,以提高性能。在本地調用時,參數大小對性能沒有影響,因為它是在同壹個堆內存中訪問的。當跨進程通信時,通常會傳遞壹個復雜的對象。如果很清楚對方只是用了幾個字段或者壹個對象引用,就不要通過整個復雜對象。例如,對象A包含8個基本類型的字段和2個復雜對象B和C..如果很清楚服務提供者只需要使用A聚合的C對象,那麽請求參數應該是C,而不是整個對象A..4)設置適當的客戶端超時,防止在業務高峰期由於服務器響應慢導致業務線程在應答時被阻塞,然後其他後續服務的消息在隊列中排隊,造成故障的擴散。5)對於重要的服務,可以單獨部署到獨立的服務線程池,與其他非核心服務隔離,保證核心服務的高效運行。6)使用Docker等輕量級OS容器部署服務,在物理資源層隔離服務,避免虛擬化後20%以上的性能損失。7)設置合理的服務調度優先級,並根據在線性能監控數據進行實時調整。2.在事務壹致性問題得到服務之前,業務使用本地事務,多個本地SQL調用可以封裝在壹個大的事務塊中。如果數據庫操作出現異常,可以回滾之前的SQL操作,只有所有SQL操作都成功才能最終提交,這樣保證了強事務壹致性,如圖2-1所示。服務後,三個數據庫操作可以分成三個獨立的數據庫訪問服務。此時,原來的本地SQL調用已經演變為遠程服務調用,無法保證事務壹致性,如圖2-2所示。圖2-2售後分布式事務問題介紹。如果服務A和服務B調用成功,A和B的SQL會被提交,最後執行服務C,其SQL操作會失敗。對於應用1的消費者,服務A和服務B的相關SQL操作已經提交,服務C已經回滾,導致交易不壹致。從圖2-2可以看出,服務後的事務不壹致主要是服務的分布式部署造成的,所以也叫分布式事務問題。2.1分布式事務設計方案壹般情況下,分布式事務是基於兩階段提交來實現的,其工作原理如圖2-3所示。圖2-3兩階段示意圖提交階段1:全局事務管理器向所有事務參與者發送準備請求;事務參與者回復全局事務管理器,不管他們是否準備好了。第二階段:全局事務管理器在收到所有事務參與者的回復後做出判斷。如果所有的交易參與者都可以提交,它將向所有的交易提交者發送提交申請,否則將回滾。事務參與者根據全局事務管理器的指令提交或回滾。分布式事務回滾的示意圖如圖2-4所示。圖2-4分布式事務回滾兩階段提交示意圖采用悲觀鎖策略,因為每個事務參與者都需要等待響應最慢的參與者,所以性能較差。第壹個問題是協議本身的成本:整個協議過程需要被鎖定,比如鎖定數據庫中的壹條記錄,需要持久化大量與事務狀態相關的操作日誌。更麻煩的是兩相鎖失效時的脆弱性,比如兩相鎖的致命缺陷:當協調器失效時,整個事務將無法繼續,直到協調器恢復,如果協調器出現磁盤失效之類的錯誤,事務將被永遠放棄。對於分布式服務框架,從功能特性上支持分布式事務是必要的。在實際業務使用過程中,如果可以通過最終壹致性解決問題,則不需要加強壹致性;如果可以避免分布式事務,那麽盡量避免在業務級別使用分布式事務。2.2分布式事務優化既然分布式事務有很多缺點,為什麽我們還在用?有沒有更好的解決方案來改進或者替代?如果只是優化分布式事務,我們發現提升的空間不大。說到底,瓶頸在於分布式事務模型本身。那麽讓我們回到問題的根源:我們為什麽需要分布式事務?因為我們需要所有資源數據的壹致性,但是所有的業務場景真的需要分布式事務提供的強壹致性嗎?大多數業務場景可以容忍短期的不壹致,不同的業務對不壹致的容忍時間不同。像銀行轉賬業務,中間有幾分鐘的不壹致,用戶通常可以理解和容忍。在大多數業務場景中,我們可以使用最終壹致性而不是傳統的強壹致性,並盡量避免使用分布式事務。在實踐中,常用的最終壹致性方案是使用具有事務功能的MQ作為中間人。它的工作原理是:在做壹個本地事務之前,向MQ發送壹個prepare消息,然後執行本地事務。如果本地事務提交成功,向MQ發送壹條提交消息,否則發送壹條回滾消息來取消之前的消息。MQ只會在收到提交確認後才傳遞消息,所以這種形式可以保證本地事務和MQ在所有正常情況下都能達到壹致性。但是分布式調用存在很多異常場景,比如網絡超時,VM宕機等等。如果系統已經成功執行了local_tx(),它還沒有時間向MQ發送commit消息,或者如果MQ由於網絡超時和其他原因沒有收到commit消息,MQ就不會傳遞prepare消息。MQ將根據策略嘗試詢問(回調)消息發送系統(checkCommit ),以檢查消息應該被傳遞還是被丟棄。經過系統確認後,MQ會投遞或者丟棄,這樣就完全保證了MQ和消息發送系統的壹致性,從而保證了消息接收系統的壹致性。3.在R&D團隊協作問題被服務化之後,尤其是在采用微服務架構之後。R&D團隊將分為幾個服務團隊,比如AWS的TwoPizzaTeam,每個團隊將負責服務的開發、測試、部署、運營和維護。隨著服務數量的擴大和R&D團隊的增加,跨團隊協作將成為制約R&D效率提升的因素。3.1 ***使用服務註冊中心為了方便開發和測試,經常離線使用壹個所有服務都可以享受的服務註冊中心。此時,壹個正在開發的服務被發布到服務註冊中心,這可能會使壹些消費者不可用。解決方案:服務提供者和開發者可以只訂閱服務(開發的服務可能依賴於其他服務)而不註冊正在開發的服務,通過直接連接測試正在開發的服務。其工作原理如圖3-1所示。圖3-1只訂閱,不發布3.2直連提供者在開發測試環境中,如果不設置公共服務註冊中心,消費者將無法獲取服務提供者的地址列表,因此只能做本地單元測試或者使用模擬堆測試。另壹個場景是,在實際測試中,服務提供者經常被部署在多個實例中。如果服務提供者出現Bug,需要遠程斷點調試,會帶來兩個問題:1)服務提供者多實例部署,遠程調試地址不確定,調試效率低。2)很多消費者可能* * *使用壹套測試調試環境,斷點調試過程可能會被其他消費者意外中斷。解決方案:繞過註冊中心,只測試指定服務商。這時,可能需要點對點的直接連接。點對點直接連接會以服務接口為單位,忽略註冊中心的提供者列表。3.3多團隊進度協調如果前端Web門戶依賴於四個不同的R&D團隊,即後臺的A、B、C和D4服務,門戶要求新功能在2周內上線。對A和B的內部需求進行優先級排序使得門戶具有更高的優先級,這可以滿足交付時間。而C、D服務所在的團隊需要同時開發優先級更高的其他服務,所以優先級相對較低,無法滿足兩周交付。在提供C和D版本之前,門戶只能通過打測試樁來完成模擬測試,但是由於C和D的服務沒有經過真正的測試,所以無法按期交付需求。應用程序依賴的服務越多,特性交付的效率就越低,交付的速度取決於依賴於最新交付的服務。如果Web門戶在後臺依賴100個服務,只要1個核心服務沒有按時交付,整個進度就會延遲。解決方案:調用鏈可以連接和顯示應用程序、服務和中間件之間的依賴關系。基於調用鏈第壹入口的交付日期作為輸入,使用依賴管理工具可以自動計算調用鏈上每個服務的最晚交付時間。通過調用鏈式分析和標準化依賴度計算工具,可以避免人為需求排序錯誤導致的需求延遲。3.4服務退化和模擬測試在實際的項目開發中,由於團隊和個體開發人員的開發節奏不壹致,消費者往往會等待依賴的服務提供者提供聯合調試版本,相互等待會拖慢項目的開發進度。解決方案:服務提供商首先確定接口,並將其提供給消費者。消費者可以將服務降級和模擬測試結合起來,在模擬測試代碼中實現容錯降級(業務發布)的業務邏輯,既完成了模擬測試,又實現了服務降級的業務邏輯開發,壹舉兩得。3.5協同調試在實際的項目開發過程中,各個R&D團隊的進度不壹致是很正常的。如果消費者等待服務商按時提供版本,往往會浪費人力資源,影響項目進度。解決方案:分布式服務框架提供了壹個模擬堆管理框架。當外圍服務商還沒有完成開發時,會將路由切換到模擬測試模式,自動調用模擬樁。業務集成在測試上線時,應能自動切換到真正的服務提供者,結合服務降級功能即可實現。3.6接口前向兼容性由於在線修復Bug、內部重新配置和需求變化,服務提供商會經常修改內部實現,包括但不限於:接口參數變化、參數字段變化、業務邏輯變化和數據表結構變化。在實際項目中,經常會出現服務提供者修改接口或數據結構,卻沒有及時通知所有消費者,導致服務調用失敗的情況。解決方案:1)制定並嚴格執行業務前向兼容規範,避免不兼容修改或未經通知周邊地區擅自修改。2)接口兼容性的技術保證:比如Thrift的IDL支持添加、修改、刪除字段,字段定義與位置無關,碼流支持亂序。4.總結服務之後,無論是服務框架還是業務服務都面臨著很多挑戰。本章摘錄了壹些更重要的問題,並給出了解決方案和最佳實踐。對於本章沒有列出的問題,服務框架開發者和用戶需要在實踐中探索,找出適合自己產品的最佳服務實踐。
  • 上一篇:Steam免費頁面遊覽
  • 下一篇:頁遊武夷傳奇公益服務
  • copyright 2024遊戲中心平台