if (isStarted) {
method.insertBefore("ProfilerUtil.start(\"" + method.getLongName() + "\");");
} else {
method.insertBefore("ProfilerUtil.entery(\"" + method.getLongName() + "\");");
}
method.insertAfter("ProfilerUtil.release();", true);
下图是性能日志工具对促销方案明细查询和保存controller调用栈的耗时统计。
**
* Desc:Dubbo异步调用辅助工具类
*
* @author wei.zw
* @since 2017年7月14日 下午4:36:08
* @version v 0.1
*/
public class RpcAsyncUtil {
private static final Logger logger = LoggerFactory.getLogger(RpcAsyncUtil.class);
/**
* dubbo异步调用,将远程调用结果组合后返回;本次耗时取决于最大的耗时
*
* @param paramList
* 需要进行远程调用所有参数列表长度
* @param pageSize
* 一次远程调用使用的列表最大长度
* @param syncCallable
* 具体dubbo调用
* @return
* @author wei.zw
*/
public static List async(List paramList, int pageSize, final SyncCallable syncCallable) {
if (pageSize < 200) {
pageSize = 200;
}
List> subList = subList(paramList, pageSize);
List>> futures = new ArrayList<>();
for (final List sub : subList) {
futures.add(RpcContext.getContext().asyncCall(new Callable>() {
@Override
public List call()
throws Exception {
return syncCallable.call(sub);
}
}));
}
List result = new ArrayList<>();
try {
for (Future> future : futures) {
List list = future.get();
if (CollectionUtils.isNotEmpty(list)) {
result.addAll(list);
}
}
} catch (Exception e) {
logger.warn(ToStringBuilder.reflectionToString(syncCallable) + ",调用异常", e);
throw new RuntimeException(e);
}
return result;
}
/**
*
*
* @param paramList
* 请求参数
* @param pageSize
* 要求参数不能小于200; 每次dubbo调用的参数大小,请设置合适值,如果数值设置过小会导致服务提供方线程数量飙升,如果设置过大可能会导致单次响应时间变长
* @param syncCallable
* 具体的dubbo调用方法,在该接口方法中不能有其他处理逻辑只能是一个dubbo 调用
* @return
* @author wei.zw
*/
public static Map async(List paramList, int pageSize, final SyncMapCallable syncCallable) {
if (pageSize < 200) {
pageSize = 200;
}
List> subList = subList(paramList, pageSize);
List>> futures = new ArrayList<>();
for (final List sub : subList) {
futures.add(RpcContext.getContext().asyncCall(new Callable>() {
@Override
public Map call()
throws Exception {
return syncCallable.call(sub);
}
}));
}
Map result = new HashMap<>();
try {
for (Future> future : futures) {
Map map = future.get();
if (MapUtils.isNotEmpty(map)) {
result.putAll(map);
}
}
} catch (Exception e) {
logger.warn(ToStringBuilder.reflectionToString(syncCallable) + ",调用异常", e);
throw new RuntimeException(e);
}
return result;
}
/**
* 拆分list
*
* @param sourceList
* @param splitSize
* @return
* @author roy
* @since 2017年1月17日
*/
private static List> subList(List sourceList, int splitSize) {
List> list = Lists.newArrayList();
if (sourceList == null || sourceList.size() == 0) {
return list;
}
if (sourceList.size() <= splitSize) {
list.add(sourceList);
return list;
}
int page = sourceList.size() / splitSize + 1;
// 模拟分页获取
for (int i = 0; i < page; i++) {
List childList = Lists.newArrayList();
for (int j = i * splitSize; j < (i + 1) * splitSize; j++) {
// 如果交表大于源列表长度 退出
if (j >= sourceList.size()) {
break;
}
childList.add(sourceList.get(j));
}
list.add(childList);
}
return list;
}
public static interface SyncCallable {
/**
* 该方法中只能是一个远程调用,不能使用其他方法
*
* @param params
* @return
* @author wei.zw
*/
public List call(List params);
}
public static interface SyncMapCallable {
/**
* 该方法中只能是一个远程调用,不能使用其他方法
*
* @param params
* @return
* @author wei.zw
*/
public Map call(List params);
}
}