在微服務如火如荼的狀況下,愈來愈多的項目開始嘗試改形成微服務架構,微服務即帶來了項目開發的方便性,又提升了運維難度以及網絡不可靠的機率.java
在說微服務的優缺點時,有對比才會更加明顯,首先說一下單體式結構mysql
在單體式架構中,系統一般採用分層架構模式(MVC),持久化層、表示層,業務邏輯層。架構主要存在如下問題:git
爲了克服以上缺點,微服務架構應運而生。微服務,又叫微服務架構。微服務就是一些協同工做的小而自治的服務.github
1. 技術異構性spring
在不一樣的服務中,可使用不一樣的技術來各自開發,只要保證服務間能相互協做便可sql
2. 彈性數據庫
當微服務中的某一個服務不可用時,不會影響整個系統,只會影響相關功能不可用編程
3. 擴展api
易於擴展,使用小的多個服務,更加易於擴展新的功能服務器
4. 簡化部署
某個服務的更新部署,不須要從新部署整個應用
5. 可組合
經過組合多個服務,能夠提供一些新的功能
6. 可替代
由於每一個微服務都比較小,從新實現某一個服務或者直接刪除該服務都是可操做的
1. 複雜度高
微服務間經過REST、RPC等形式交互,相對於單體模式,須要考慮被調用方故障、過載、消息丟失等各類異常狀況,代碼邏輯更加複雜。
對於微服務間的事務性操做,由於不一樣的微服務採用了不一樣的數據庫,將沒法利用數據庫自己的事務機制保證一致性,須要引入二階段提交等技術。
同時,在微服務間存在少部分共用功能但又沒法提取成微服務時,各個微服務對於這部分功能一般須要重複開發,或至少要作代碼複製,以免微服務間的耦合,增長了開發成本。
2. 運維複雜
在採用微服務架構時,系統由多個獨立運行的微服務構成,須要一個設計良好的監控系統對各個微服務的運行狀態進行監控。運維人員須要對系統有細緻的瞭解纔對夠更好的運維繫統。
3. 影響性能
相對於單體架構,微服務的間經過REST、RPC等形式進行交互,通訊的時延會受到較大的影響。
正如上面所說
對於微服務間的事務性操做,由於不一樣的微服務採用了不一樣的數據庫,將沒法利用數據庫自己的事務機制保證一致性,須要引入二階段提交等技術。
在單體項目中,很容易作到事務控制,而在多個服務之間很難實現
假設服務調用以下:
A B C D 的事務均在各個服務控制,如何作到,統一協調,保證數據的一致性?
XA是一個分佈式事務協議,由提出。XA中大體分爲兩部分:事務管理器和本地資源管理器。其中本地資源管理器每每由數據庫實現,好比Oracle、DB2這些商業數據庫都實現了XA接口,而事務管理器做爲全局的調度者,負責各個本地資源的提交和回滾。XA實現分佈式事務的原理以下:
第一階段:
第二階段:
總的來講,XA協議比較簡單,並且一旦商業數據庫實現了XA協議,使用分佈式事務的成本也比較低。可是,XA也有致命的缺點,那就是性能不理想,特別是在交易下單鏈路,每每併發量很高,XA沒法知足高併發場景。XA目前在商業數據庫支持的比較理想,在mysql數據庫中支持的不太理想,mysql的XA實現,沒有記錄prepare階段日誌,主備切換回致使主庫與備庫數據不一致。許多nosql也沒有支持XA,這讓XA的應用場景變得很是狹隘。
所謂的消息事務就是基於消息中間件的兩階段提交,本質上是對消息中間件的一種特殊利用,它是將本地事務和發消息放在了一個分佈式事務裏,保證要麼本地操做成功成功而且對外發消息成功,要麼二者都失敗,開源的RocketMQ就支持這一特性.
該方案採用最終一致的,犧牲了一致性,換來了性能的大幅度提高。存在形成數據不一致的風險
所謂的TCC編程模式,也是兩階段提交的一個變種。TCC提供了一個編程框架,將整個業務邏輯分爲三塊:Try、Confirm和Cancel三個操做。以在線下單爲例,Try階段會去扣庫存,Confirm階段則是去更新訂單狀態,若是更新訂單失敗,則進入Cancel階段,會去恢復庫存。總之,TCC就是經過代碼人爲實現了兩階段提交,不一樣的業務場景所寫的代碼都不同,複雜度也不同,所以,這種模式並不能很好地被複用。
LCN分佈式事務框架的核心功能是對本地事務的協調控制,框架自己並不建立事務,只是對本地事務作協調控制。所以該框架與其餘第三方的框架兼容性強,支持全部的關係型數據庫事務,支持多數據源,支持與第三方數據庫框架一塊使用(例如 sharding-jdbc),在使用框架的時候只須要添加分佈式事務的註解便可,對業務的侵入性低。LCN框架主要是爲微服務框架提供分佈式事務的支持,在微服務框架上作了進一步的事務機制優化,在一些負載場景上LCN事務機制要比本地事務機制的性能更好,4.0之後框架開方了插件機制可讓更多的第三方框架支持進來
目前 LCN爲 4.1 版本
主要特色:
採用強一致性方案,事務要不所有成功,要不所有失敗,保證了事務的一致性,代碼簡單,原有項目只需引入相關 jar
包,並在須要參與的事務的方法添加註解便可,節省了代碼改形成本.
Spring Cloud示例:
添加依賴
<properties> <lcn.last.version>4.1.0</lcn.last.version> </properties> <dependency> <groupId>com.codingapi</groupId> <artifactId>transaction-springcloud</artifactId> <version>${lcn.last.version}</version> </dependency> <dependency> <groupId>com.codingapi</groupId> <artifactId>tx-plugins-db</artifactId> <version>${lcn.last.version}</version> </dependency>
在須要執行的事務上添加註解
@Override @TxTransaction(isStart = true) @Transactional public int save() { }
其中 @TxTransaction(isStart = true)
爲lcn 事務控制註解,其中isStart = true
表示該方法是事務的發起方例如,服務A 須要調用服務B,服務B 須要調用服務C,此時 服務A爲服務發起方,其他爲參與方,參與方只需@Transaction
便可
在測試時須要將 事務管理服務啓動 txManager
, 具體示例參看:https://www.txlcn.org
ByteTCC是一個基於TCC(Try/Confirm/Cancel)機制的分佈式事務管理器。兼容JTA,能夠很好的與EJB、Spring等容器(本文檔下文說明中將以Spring容器爲例)進行集成。
ByteTCC特性
一、支持Spring容器的聲明式事務管理;
二、支持普通事務、TCC事務、業務補償型事務等事務機制;
三、支持多數據源、跨應用、跨服務器等分佈式事務場景;
四、支持長事務;
五、支持dubbo服務框架;
六、支持spring cloud;
該實現方式,須要在業務層編寫對應的 tcc(Try/Confirm/Cancel) 方法,開發須要必定的成本,同時某些業務可能沒法保證數據可回滾
參考: