
版權(quán)申明
原創(chuàng)文章:本博所有原創(chuàng)文章,歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明出處,并聯(lián)系本人取得授權(quán)。
版權(quán)郵箱地址:banquan@mrdwy.com
對于Dubbo之類的RPC接口,其本質(zhì)就是封裝了接口的遠程調(diào)用代碼,消費者調(diào)用服務(wù)者不需要知道中間的遠程調(diào)用具體實現(xiàn),從而簡化開發(fā),其底層遠程調(diào)用本質(zhì)還是使用了例如http、hessian等網(wǎng)絡(luò)協(xié)議,既然是遠程訪問必然也與其它的接口一樣由于網(wǎng)絡(luò)訪問的不可靠導致各種各樣接口調(diào)用不通的情況發(fā)生,為了應(yīng)對這種情況,在請求dubbo這樣的遠程接口時,都需要加上相應(yīng)的防御代碼,增加上重試機制。
雖然dubbo本身可以配置重試機制,設(shè)置重試次數(shù)等參數(shù),但是我在實際使用過程中發(fā)現(xiàn)不是那么可靠,因此自己實現(xiàn)了一個工具類,可以方便的為遠程調(diào)用增加上重試功能,并且可以按需使用,對于穩(wěn)定性要求不是特別高的業(yè)務(wù),或者是接口不提供冪等支持的接口可以不使用,支持冪等,并且穩(wěn)定性要求高的業(yè)務(wù)單獨使用。
代碼如下
package com.tcrow.it.commons.util;
import com.tcrow.it.commons.ResultMsg;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.function.Supplier;
/**
* @author tcrow.luo
* @date 2019/5/15.
* dubbo調(diào)用輔助工具類
*/
public class DubboUtil {
private static Logger log = LoggerFactory.getLogger(DubboUtil.class);
public final static Integer MAX_RETRY_TIMES = 3;
/**
* 發(fā)起調(diào)用,如果發(fā)生異常,將會嘗試重新調(diào)用接口,最大重試3次
* example:
* ResultMsg resultMsg = DubboUtil.apply(() -> xxxService.callrpc(pojo));
* @param supplier
* @return
*/
public static ResultMsg apply(Supplier supplier) {
return apply(supplier, 0);
}
private static ResultMsg apply(Supplier supplier, Integer retry) {
ResultMsg resultMsg;
try {
resultMsg = (ResultMsg) supplier.get();
} catch (Throwable e) {
log.warn("Invoke dubbo method :[{}], throw error:[{}]", new String[]{supplier.toString(), e.getMessage()});
if (retry >= MAX_RETRY_TIMES) {
throw e;
}
return apply(supplier, retry + 1);
}
return resultMsg;
}
}
使用方法也很簡單:
ResultMsg resultMsg = DubboUtil.apply(() -> xxxService.callrpc(pojo));
ResultMsg 是自定義的統(tǒng)一返回類型,這個可以根據(jù)業(yè)務(wù)情況自己定義,或者直接用Object也行,然后根據(jù)接口實際返回對象類型轉(zhuǎn)換Object
xxxService 就是dubbo接口
callrpc 指的是具體dubbo的接口方法
這里是用了jdk1.8的lamadb表達式,主要是構(gòu)造一個Supplier類型,不清楚的同學可以自行了解一下Lamadb表達式,和java.util.function包的功能。