版权申明
原创文章:本博所有原创文章,欢迎转载,转载请注明出处,并联系本人取得授权。
版权邮箱地址:banquan@mrdwy.com
对于Dubbo之类的RPC接口,其本质就是封装了接口的远程调用代码,消费者调用服务者不需要知道中间的远程调用具体实现,从而简化开发,其底层远程调用本质还是使用了例如http、hessian等网络协议,既然是远程访问必然也与其它的接口一样由于网络访问的不可靠导致各种各样接口调用不通的情况发生,为了应对这种情况,在请求dubbo这样的远程接口时,都需要加上相应的防御代码,增加上重试机制。
虽然dubbo本身可以配置重试机制,设置重试次数等参数,但是我在实际使用过程中发现不是那么可靠,因此自己实现了一个工具类,可以方便的为远程调用增加上重试功能,并且可以按需使用,对于稳定性要求不是特别高的业务,或者是接口不提供幂等支持的接口可以不使用,支持幂等,并且稳定性要求高的业务单独使用。
代码如下
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调用辅助工具类
*/
public class DubboUtil {
private static Logger log = LoggerFactory.getLogger(DubboUtil.class);
public final static Integer MAX_RETRY_TIMES = 3;
/**
* 发起调用,如果发生异常,将会尝试重新调用接口,最大重试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 是自定义的统一返回类型,这个可以根据业务情况自己定义,或者直接用Object也行,然后根据接口实际返回对象类型转换Object
xxxService 就是dubbo接口
callrpc 指的是具体dubbo的接口方法
这里是用了jdk1.8的lamadb表达式,主要是构造一个Supplier类型,不清楚的同学可以自行了解一下Lamadb表达式,和java.util.function包的功能。
网友评论