概述
在當(dāng)前廣泛流行的分布式系統(tǒng)中,確保系統(tǒng)數(shù)據(jù)的一致性和正確性是一項(xiàng)重大挑戰(zhàn)。為了解決分布式事務(wù)問題,涌現(xiàn)了許多理論和業(yè)務(wù)實(shí)踐,其中BASE理論是目前業(yè)界廣泛接受的分布式一致性理論。
基于BASE理論,采用柔性事務(wù)并優(yōu)先保障系統(tǒng)的可用性和數(shù)據(jù)的最終一致性已逐漸成為技術(shù)共識(shí)。 為了確保分布式服務(wù)的可用性和數(shù)據(jù)一致性,并防止由于網(wǎng)絡(luò)抖動(dòng)、連接超時(shí)等問題導(dǎo)致短時(shí)不可用的情況,根據(jù)"墨菲定律",在核心流程中增加重試和數(shù)據(jù)核對(duì)校驗(yàn)的動(dòng)作成為提高系統(tǒng)魯棒性常用的技術(shù)方案。
在此背景下EasyRetry應(yīng)運(yùn)而生。EasyRetry是一款基于BASE思想實(shí)現(xiàn)的分布式服務(wù)重試組件,旨在通過重試機(jī)制確保數(shù)據(jù)的最終一致性。它提供了控制臺(tái)任務(wù)觀測、可配置的重試策略、重試后執(zhí)行回調(diào)以及豐富地告警配置等功能。
通過這些手段,可以對(duì)異常數(shù)據(jù)進(jìn)行全面監(jiān)測和回放,從而在確保系統(tǒng)高可用性的同時(shí),大大提升數(shù)據(jù)的一致性。
通常的業(yè)務(wù)場景有:
- 保障系統(tǒng)穩(wěn)定性,減少網(wǎng)絡(luò)抖動(dòng)導(dǎo)致異常,增加重試能力
- 保障服務(wù)容錯(cuò)性,對(duì)核心流程進(jìn)行拆分,在業(yè)務(wù)低峰期進(jìn)行數(shù)據(jù)核對(duì)
- 保證信息的可達(dá)性,在服務(wù)間通知時(shí)增加重試
但由于正常業(yè)務(wù)場景較難觸發(fā)重試流程,從而導(dǎo)致研發(fā)測試對(duì)重試場景和流量并不重視,始終處于重要但無序的"管理真空"
Easy-RETRY 是一個(gè)針對(duì)業(yè)務(wù)系統(tǒng)重試流量的治理平臺(tái),其自身具有高可用高性能高負(fù)載的特點(diǎn),服務(wù)特性有:
- 支持千萬級(jí)別的重試流量分派
- 支持流量容量擴(kuò)容,自動(dòng)識(shí)別并處理
- 支持流量處理節(jié)點(diǎn)水平擴(kuò)容
- 高效利用系統(tǒng)資源支持高并發(fā)
- 支持多種算法調(diào)度客戶端執(zhí)行
- 打包上報(bào),支持高并發(fā)業(yè)務(wù)場景
- 加密通訊,保障信息安全
重試方案對(duì)比
設(shè)計(jì)思想
流量管理平臺(tái)預(yù)覽
地址: http://preview.easyretry.com/ 賬號(hào): admin 密碼: admin
場景應(yīng)用
為了小伙伴們能更快了解EasyRetry的使用場景和優(yōu)勢,以下新增了一些模擬案例僅供大家參考。 同時(shí)期待大家積極參與并分享自己在項(xiàng)目中使用EasyRetry的經(jīng)驗(yàn)和案例,共同推動(dòng)技術(shù)的發(fā)展和應(yīng)用的實(shí)踐。
這樣可以讓更多需要使用EasyRetry的小伙伴們找到適合自己的應(yīng)用場景, 并充分利用EasyRetry的優(yōu)勢,以提升系統(tǒng)的可靠性和穩(wěn)定性。
強(qiáng)通知場景
強(qiáng)通知性
在某些業(yè)務(wù)場景下,需要強(qiáng)制保證將通知、消息等數(shù)據(jù)發(fā)送到目標(biāo)端接口,但由于網(wǎng)絡(luò)的不確定性以及目標(biāo)系統(tǒng)、應(yīng)用、服務(wù)的不確定性,可能會(huì)造成通知消息的發(fā)送失敗。
此類場景下可以使用LOCAL_REMOTE
或者ONLY_REMOTE
模式進(jìn)行重試。
發(fā)送MQ場景
眾所周知消息隊(duì)列的異步、削峰、解耦優(yōu)點(diǎn), 在業(yè)務(wù)系統(tǒng)承擔(dān)著十分重要的角色,如果保障消息的可達(dá)性就尤為重要了。
下面模擬一個(gè)常見的的下單流程。
訂單中心下單完成后回拋出下單成功消息從而解耦了訂單和其他業(yè)務(wù)系統(tǒng)的耦合關(guān)系,其他相關(guān)的業(yè)務(wù)系統(tǒng)只需要監(jiān)聽訂單的下單成功的消息即可完成自己的業(yè)務(wù)邏輯。
但是若由于網(wǎng)絡(luò)的不穩(wěn)定、消息隊(duì)列故障等等,可能導(dǎo)致消息未發(fā)送出去,這時(shí)候就需要增加重試流程來保障消息的強(qiáng)可達(dá)性。
然后接入EasyRetry后將變的非常簡單,您只需要簡單的一個(gè)注解就保障強(qiáng)可達(dá)性
以下代碼案例僅供參考文章來源:http://www.zghlxwxcb.cn/news/detail-632709.html
@Retryable(scene = "create-order-success", retryStrategy = RetryType.ONLY_REMOTE)
public void sendCreateOrderSuccessMessage(Message message) {
......
// 發(fā)送消息
mqProducer.publish("主題", "key", message);
}
如果您不想使用注解的方式您可是使用手動(dòng)模式
public void createOrder(Order order) {
// 其他邏輯
// 發(fā)送消息
try {
mqProducer.publish("主題", "key", order);
} catch (Exception e) {
// 發(fā)送出現(xiàn)異常
EasyRetryTemplate retryTemplate = RetryTaskTemplateBuilder.newBuilder()
.withExecutorMethod(RetrySendMqMessageExecutorMethod.class)
.withParam(order)
.withScene(RetrySendMqMessageExecutorMethod.SCENE)
.build();
retryTemplate.executeRetry();
}
}
@ExecutorMethodRegister(scene = RetrySendMqMessageExecutorMethod.SCENE, async = true, forceReport = true)
public class RetrySendMqMessageExecutorMethod implements ExecutorMethod {
public static final String SCENE = "retrySendMqMessageExecutorMethod";
@Override
public Object doExecute(Object objs) {
Object[] params = (Object[]) objs;
// 發(fā)送消息
mqProducer.publish("主題", "key", params[0]);
return null;
}
}
回調(diào)場景
這里引用一個(gè)使用EasyRetry的小伙伴重試框架-Easy-Retry接入之路,他們線上真實(shí)的使用場景。
他們一個(gè)paas平臺(tái), 其中功能模塊有“事件中心”,“審核中心”,“支付中心”等相關(guān)的一些組件。他們都有一個(gè)類似的東西,當(dāng)我發(fā)起事件的時(shí)候,需要將事件通知到其他的應(yīng)用, 比如
- 【審核中心】當(dāng)我審核的時(shí)候需要將審核結(jié)果返回給其他應(yīng)用,
- 【支付中心】當(dāng)我支付完成后也會(huì)將結(jié)果推送給其他應(yīng)用。
然而,我們的其他應(yīng)用可能會(huì)有不可用的狀態(tài), 可能會(huì)導(dǎo)致回調(diào)通知的時(shí)候會(huì)報(bào)錯(cuò), 所以不難想象到我們需要做一個(gè)重試機(jī)制來保障回調(diào)的可達(dá)性。
下面是一個(gè)支付中心的調(diào)用過程
用戶在商品中心下單然后通過支付中心喚起收銀臺(tái)進(jìn)行付款,第三方支付平臺(tái)回調(diào)支付中心,支付平臺(tái)回調(diào)商品中心完成業(yè)務(wù)流程;
但是若回調(diào)失敗了就會(huì)導(dǎo)致商品中心和 支付中心數(shù)據(jù)不一致,這肯定不是我們所期望的。
所以需要新增一個(gè)重試機(jī)制來保障數(shù)據(jù)的最終一致性。
以下代碼案例僅供參考
@Retryable(scene = "callbackProductCenter", retryStrategy = RetryType.ONLY_REMOTE)
public void callbackProductCenter(CallbackDTO callback) {
......
// 回調(diào)商品中心
String responseStr = restTemplate.postForObject("第三方接口", "參數(shù)", String.class);
}
如果您不想使用注解的方式您可是使用手動(dòng)模式
public void callbackProductCenter(CallbackDTO callback) {
// 其他邏輯
try {
// 回調(diào)商品中心
String responseStr = restTemplate.postForObject("第三方接口", "參數(shù)", String.class);
} catch (Exception e) {
// 發(fā)送出現(xiàn)異常
EasyRetryTemplate retryTemplate = RetryTaskTemplateBuilder.newBuilder()
.withExecutorMethod(RetrySendMqMessageExecutorMethod.class)
.withParam(order)
.withScene(RetrySendMqMessageExecutorMethod.SCENE)
.build();
retryTemplate.executeRetry();
}
}
@ExecutorMethodRegister(scene = CallbackProductCenterExecutorMethod.SCENE, async = true, forceReport = true)
public class CallbackProductCenterExecutorMethod implements ExecutorMethod {
public static final String SCENE = "callbackProductCenterExecutorMethod";
@Override
public Object doExecute(Object objs) {
Object[] params = (Object[]) objs;
// 回調(diào)商品中心
String responseStr = restTemplate.postForObject("第三方接口", "參數(shù)", String.class);
return null;
}
}
異步場景
在一些核心的接口上,我們總是想不斷的提高接口的性能,我們知道提高接口性能的方式常用的就是異步、緩存、并行等,
這里我們說說異步,比如下面一個(gè)場景
下單完成后會(huì)有一些非核心的流程,主要特點(diǎn)實(shí)時(shí)性要求不高、耗時(shí)比較高的操作等;
一般會(huì)把這些流程進(jìn)行異步化操作、進(jìn)程異步化: 比如可以通過發(fā)送MQ消息, 如果保存MQ的可達(dá)性可以參考發(fā)送MQ場景
??????
線程異步化: 開啟一個(gè)異步線程進(jìn)行異步處理, 但是出現(xiàn)異常就會(huì)導(dǎo)致數(shù)據(jù)丟失,因此需要增加重試保證數(shù)據(jù)的一致性, 可以使用LOCAL_REMOTE先本地重試,如果本地重試仍未解決就上報(bào)服務(wù)端
以下代碼案例僅供參考
@Retryable(scene = "sendEmail", retryStrategy = RetryType.LOCAL_REMOTE)
public void sendEmail(EmailDTO email) {
......
// 發(fā)送下單確認(rèn)郵件
String responseStr = restTemplate.postForObject("郵箱地址", email, String.class);
}
文章來源地址http://www.zghlxwxcb.cn/news/detail-632709.html
到了這里,關(guān)于OpenSource - 分布式重試平臺(tái)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!