概述
servicecomb-saga是一個(gè)微服務(wù)應(yīng)用的數(shù)據(jù)最終一致性解決方案,是一種基于在2PC和TCC兩者之間的框架,簡(jiǎn)單的說(shuō)是依賴(lài)協(xié)調(diào)器的TCC方式。
特性
- 高可用。支持集群模式。
- 高可靠。所有的事務(wù)事件都持久存儲(chǔ)在數(shù)據(jù)庫(kù)中。
- 高性能。事務(wù)事件是通過(guò)gRPC來(lái)上報(bào)的,且事務(wù)的請(qǐng)求信息是通過(guò)Kyro進(jìn)行序列化和反序列化的。
- 低侵入。僅需2-3個(gè)注解和編寫(xiě)對(duì)應(yīng)的補(bǔ)償方法即可進(jìn)行分布式事務(wù)。
- 部署簡(jiǎn)單。可通過(guò)Docker快速部署。
- 支持前向恢復(fù)(重試)及后向恢復(fù)(補(bǔ)償)。
saga架構(gòu)圖

- alpha充當(dāng)協(xié)調(diào)者的角色,主要負(fù)責(zé)對(duì)事務(wù)的事件進(jìn)行持久化存儲(chǔ)以及協(xié)調(diào)子事務(wù)的狀態(tài),使其得以最終與全局事務(wù)的狀態(tài)保持一致。
- omega是微服務(wù)中內(nèi)嵌的一個(gè)agent,負(fù)責(zé)對(duì)網(wǎng)絡(luò)請(qǐng)求進(jìn)行攔截并向alpha上報(bào)事務(wù)事件,并在異常情況下根據(jù)alpha下發(fā)的指令執(zhí)行相應(yīng)的補(bǔ)償操作。
Omega內(nèi)部運(yùn)行機(jī)制
omega是微服務(wù)中內(nèi)嵌的一個(gè)agent。當(dāng)服務(wù)收到請(qǐng)求時(shí),omega會(huì)將其攔截并從中提取請(qǐng)求信息中的全局事務(wù)id作為其自身的全局事務(wù)id(即Saga事件id),并提取本地事務(wù)id作為其父事務(wù)id。在預(yù)處理階段,alpha會(huì)記錄事務(wù)開(kāi)始的事件;在后處理階段,alpha會(huì)記錄事務(wù)結(jié)束的事件。因此,每個(gè)成功的子事務(wù)都有一一對(duì)應(yīng)的開(kāi)始及結(jié)束事件。

服務(wù)間通信流程
服務(wù)間通信的流程與Zipkin的類(lèi)似。在服務(wù)生產(chǎn)方,omega會(huì)攔截請(qǐng)求中事務(wù)相關(guān)的id來(lái)提取事務(wù)的上下文。在服務(wù)消費(fèi)方,omega會(huì)在請(qǐng)求中注入事務(wù)相關(guān)的id來(lái)傳遞事務(wù)的上下文。通過(guò)服務(wù)提供方和服務(wù)消費(fèi)方的這種協(xié)作處理,子事務(wù)能連接起來(lái)形成一個(gè)完整的全局事務(wù)。

具體處理流程
成功場(chǎng)景
成功場(chǎng)景下,每個(gè)開(kāi)始的事件都會(huì)有對(duì)應(yīng)的結(jié)束事件。

異常場(chǎng)景
異常場(chǎng)景下,omega會(huì)向alpha上報(bào)中斷事件,然后alpha會(huì)向該全局事務(wù)的其它已完成的子事務(wù)發(fā)送補(bǔ)償指令,確保最終所有的子事務(wù)要么都成功,要么都回滾。

超時(shí)場(chǎng)景
超時(shí)場(chǎng)景下,已超時(shí)的事件會(huì)被alpha的定期掃描器檢測(cè)出來(lái),與此同時(shí),該超時(shí)事務(wù)對(duì)應(yīng)的全局事務(wù)也會(huì)被中斷。

QuickStart
引入Saga的依賴(lài)
<dependency>
<groupId>org.apache.servicecomb.saga</groupId>
<artifactId>omega-spring-starter</artifactId>
<version>${saga.version}</version>
</dependency>
<dependency>
<groupId>org.apache.servicecomb.saga</groupId>
<artifactId>omega-transport-resttemplate</artifactId>
<version>${saga.version}</version>
</dependency>
注意: 請(qǐng)將${saga.version}更改為實(shí)際的版本號(hào)。
添加Saga的注解及相應(yīng)的補(bǔ)償方法
以一個(gè)轉(zhuǎn)賬應(yīng)用為例:
- 在應(yīng)用入口添加 @EnableOmega 的注解來(lái)初始化omega的配置并與alpha建立連接。
@SpringBootApplication
@EnableOmega
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
- 在全局事務(wù)的起點(diǎn)添加 @SagaStart 的注解。
@SagaStart(timeout=10)
public boolean transferMoney(String from, String to, int amount) {
transferOut(from, amount);
transferIn(to, amount);
}
注意: 默認(rèn)情況下,超時(shí)設(shè)置需要顯式聲明才生效。
- 在子事務(wù)處添加 @Compensable 的注解并指明其對(duì)應(yīng)的補(bǔ)償方法。
@Compensable(timeout=5, compensationMethod="cancel")
public boolean transferOut(String from, int amount) {
repo.reduceBalanceByUsername(from, amount);
}
public boolean cancel(String from, int amount) {
repo.addBalanceByUsername(from, amount);
}
注意: 實(shí)現(xiàn)的服務(wù)和補(bǔ)償必須滿足冪等的條件。
注意: 默認(rèn)情況下,超時(shí)設(shè)置需要顯式聲明才生效。
注意: 若全局事務(wù)起點(diǎn)與子事務(wù)起點(diǎn)重合,需同時(shí)聲明 @SagaStart 和 @Compensable 的注解。
- 對(duì)轉(zhuǎn)入服務(wù)重復(fù)第三步即可。