文章目錄
- 前言
- 一、微服務保護
- 二、Sentinel
- 2.1 微服務整合
- 2.2 簇點鏈路
- 2.3 請求限流
- 2.4 線程隔離
- 2.5 服務熔斷
- 三、分布式事務
- 3.1 Seata
- 3.1.1 Seata架構
- 3.1.2 部署TC服務
- 3.1.3 微服務集成Seata
- 3.2 XA模式
- 3.3 AT模式
前言
微服務之間為什么會雪崩?怎么解決雪崩問題?
如何采用Sentiel整合微服務實現請求限流、線程隔離以及服務熔斷問題。
怎么集成Seata解決微服務之間引發的分布式事務問題?
一、微服務保護
1、請求限流
限制訪問微服務的請求的并發量,避免服務因流量激增出現故障。
2、線程隔離
艙壁模式,模擬船艙隔板的防水原理。通過限定每個業務能使用的線程數量而將故障業務隔離,避免故障擴散。
例如:查詢購物車的時候需要查詢商品,為了避免因商品服務出現故障導致購物車服務級聯失敗,我們可以把購物車業務中查詢商品的部分隔離起來,限制可用的線程資源,即便商品服務出現故障,最多導致查詢購物車業務故障,并且可用的線程資源也被限定在一定范圍,不會導致整個購物車服務崩潰。
3、服務熔斷
由斷路器統計請求的異常比例或慢調用比例,如果超出閾值則會熔斷該業務,則攔截該接口的請求。
熔斷期間,所有請求快速失敗,全都走fallback邏輯。
4、失敗處理
給業務編寫一個調用失敗時的處理的邏輯,稱為fallback。當調用出現故障(比如無線程可用)時,按照失敗處理邏輯執行業務并返回,而不是直接拋出異常。
二、Sentinel
Sentinel是阿里巴巴開源的一款服務保護框架。
2.1 微服務整合
1、引入sentinel依賴
<!--sentinel-->
<dependency><groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2、配置控制臺。
spring:cloud: sentinel:transport:dashboard: localhost:8090 #訪問地址
3、訪問微服務塊的任意斷點,如訪問查詢購物車接口,sentinel的客戶端就會將服務訪問的信息提交到sentinel-dashboard控制臺
2.2 簇點鏈路
單機調用鏈路。是一次請求進入服務后經過的每一個被Sentinel監控的資源鏈。默認Sentinel會監控SpringMVC的每一個Endpoint(http接口)。限流、熔斷等都是針對簇點鏈路中的資源設置的。而資源名默認就是接口的請求路徑。
打開Sentinel的請求方式前綴,把請求方式 + 請求路徑作為簇點資源名。
2.3 請求限流
在簇點鏈路后面點擊流控按鈕,即可對其做限流配置。
簇點資源的流量限制在了每秒6個,也就是最大QPS為6.
2.4 線程隔離
解決服務故障
實現步驟
1、OpenFeign整合Sentinel,為了開啟遠程調用feignclient作為簇點,可以被流量監控。
feign:sentinel:enabled: true # 開啟feign對sentinel的支持
2、配置線程隔離
2.5 服務熔斷
請求失敗不應該拋異常,為了讓用戶體驗更好,可以返回一些默認數據或者友好提示,查詢失敗設置一個降級處理邏輯。
對于這種不太健康的接口,應該直接停止調用,避免影響到當前服務。也就是將接口熔斷。
實現步驟
1、編寫降級邏輯
給FeignClient編寫失敗后的降級邏輯兩種方式:
- 方式一:FallbackClass,無法對遠程調用的異常做處理
- 方式二:FallbackFactory,可以對遠程調用的異常做處理,我們一般選擇這種方式。
步驟1:定義一個降級處理類ItemClientFallback,實現FallbackFactory。
@Slf4j
public class ItemClientFallback implements FallbackFactory<ItemClient> {@Overridepublic ItemClient create(Throwable cause) {return new ItemClient() {@Overridepublic List<ItemDTO> queryItemByIds(Collection<Long> ids) {log.error("遠程調用ItemClient#queryItemByIds方法出現異常,參數:{}", ids, cause);// 查詢購物車允許失敗,查詢失敗,返回空集合return CollUtils.emptyList();}@Overridepublic void deductStock(List<OrderDetailDTO> items) {// 庫存扣減業務需要觸發事務回滾,查詢失敗,拋出異常throw new BizIllegalException(cause);}};}
}
步驟2:編寫一個配置類,在配置類中將ItemClientFallback注冊為一個Bean。
public class DefaultFeignConfig {@Beanpublic Logger.Level feginLogLevel(){return Logger.Level.FULL;}@Beanpublic ItemClientFallbackFactory itemClientFallbackFactory(){return new ItemClientFallbackFactory();}
}
步驟3:在ItemClient接口中使用ItemClientFallbackFactory
@FeignClient(value = "item-service",fallbackFactory = ItemClientFallbackFactory.class)
public interface ItemClient {...}
2、服務熔斷
由斷路器統計服務調用的異常比例、慢請求比例,如果超出閾值則會熔斷該服務。即攔截訪問該服務的一切請求;而當服務恢復時,斷路器會放行訪問該服務的請求。
斷路器的工作狀態切換有一個狀態機來控制
- closed:關閉狀態,斷路器放行所有請求,并開始統計異常比例、慢請求比例。超過閾值則切換到open狀態
- open:打開狀態,服務調用被熔斷,訪問被熔斷服務的請求會被拒絕,快速失敗,直接走降級邏輯。Open狀態持續一段時間后會進入half-open狀態
- half-open:半開狀態,放行一次請求,根據執行結果來判斷接下來的操作。
- 請求成功:則切換到closed狀態
- 請求失敗:則切換到open狀態
點擊控制臺中簇點資源后的熔斷按鈕,即可配置熔斷策略
- RT超過200毫秒的請求調用就是慢調用
- 統計最近1000ms內的最少5次請求,如果慢調用比例不低于0.5,則觸發熔斷
- 熔斷持續時長20s
三、分布式事務
如果一個業務需要多個服務合作完成,而且每一個服務都有事務,多個事務必須同時成功或失敗,這樣的事務就是分布式事務。其中的每個服務的事務就是一個分支事務。整個業務稱為全局事務。
3.1 Seata
參與事務的多個分支事務互相無感知,不知道彼此的執行狀態。找一個統一的事務協調者,與多個分支事務通信,檢測每個分支事務的執行狀態,保證全局事務下的每一個分支事務同時成功或失敗即可。
3.1.1 Seata架構
- TC (Transaction Coordinator) - 事務協調者:維護全局和分支事務的狀態,協調全局事務提交或回滾。
- TM (Transaction Manager) - 事務管理器:定義全局事務的范圍、開始全局事務、提交或回滾全局事務。
- RM (Resource Manager) - 資源管理器:管理分支事務,與TC交談以注冊分支事務和報告分支事務的狀態,并驅動分支事務提交或回滾。
3.1.2 部署TC服務
TC服務是事務協調中心,是一個獨立的微服務,需要單獨部署。
基于數據庫持久化存儲,采用docker部署seata
具體部署不做說明。
3.1.3 微服務集成Seata
參與分布式事務的每一個微服務都需要集成Seata
實現步驟
1、引入依賴
為了方便各個微服務集成seata,需要把seata配置共享到nacos
<!--統一配置管理--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!--讀取bootstrap文件--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId></dependency><!--seata--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId></dependency>
2、在nacos中配置seata
3、在微服務中添加bootstrap.yaml文件,定義nacos配置信息。
4、添加數據庫表。seata的客戶端在解決分布式事務的時候需要記錄一些中間數據,保存在數據庫中。要講數據庫表分別導入不同的微服務當中。
5、測試分布式事務
在訂單業務方法上的@Transactional注解改為Seata提供的**@GlobalTransactional**
@GlobalTransactional注解就是在標記事務的起點,將來TM就會基于這個方法判斷全局事務范圍,初始化全局事務。
3.2 XA模式
Seata支持四種不同的分布式事務解決方案: XA、TCC、 AT、SAGA
XA 規范描述了全局的TM與局部的RM之間的接口,幾乎所有主流的數據庫都對 XA 規范提供了支持。
A是規范,目前主流數據庫都實現了這種規范,實現的原理都是基于兩階段提交。
優點
- 事務的強一致性,滿足ACID原則
- 常用數據庫都支持,實現簡單,并且沒有代碼侵入
缺點:
- 因為一階段需要鎖定數據庫資源,等待二階段結束才釋放,性能較差
- 依賴關系型數據庫實現事務
seata中實現XA
1、Nacos中的共享shared-seata.yaml配置文件中設置
seata:data-source-proxy-mode: XA
2、@GlobalTransactional標記分布式事務的入口方法
3.3 AT模式
Seata主推的是AT模式,AT模式同樣是分階段提交的事務模型,不過缺彌補了XA模型中資源鎖定周期過長的缺陷。
流程圖
AT模式與XA模式最大的區別是什么?
XA模式一階段不提交事務,鎖定資源;AT模式一階段直接提交,不鎖定資源。
XA模式依賴數據庫機制實現回滾;AT模式利用數據快照實現數據回滾。
XA模式強一致;AT模式最終一致