使用dubbo 2.7.4.1进行dubbo泛化同步调用,相比使用dubbo 2.6.2进行dubbo泛化同步调用,2.7.4.1的QPS大概是2.6.2的60%,配置相同,只是高版本某些命名空间不同,是还有什么配置吗?
public class DubboProxyService {
private final Map<String, ApplicationConfig> APPLICATION_CONFIG_MAP = new ConcurrentHashMap<>();
private final Map<String, List<RegistryConfig>> REGISTRY_CONFIG_MAP = new ConcurrentHashMap<>();
private final List<String> DUBBO_LOADBALANCE_LIST = new ArrayList<String>() {{
// com.alibaba.dubbo.rpc.cluster.loadbalance.RandomLoadBalance
add("random");
// com.alibaba.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance
add("roundrobin");
// com.alibaba.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance
add("leastactive");
// com.alibaba.dubbo.rpc.cluster.loadbalance.ConsistentHashLoadBalance
add("consistenthash");
}};
private final Splitter DUBBO_REGISTRIES_SPLITTER = Splitter.on(",").omitEmptyStrings().trimResults();
public Object genericInvoker(final Map<String, Object> paramMap, final DubboSelectorHandle dubboSelectorHandle, final DubboRuleHandler dubboRuleHandler) {
ReferenceConfig<GenericService> reference = buildReferenceConfig(dubboSelectorHandle, dubboRuleHandler, paramMap.get(Constants.DUBBO_INTERFACE_NAME).toString());
ReferenceConfigCache configCache = ReferenceConfigCache.getCache();
GenericService genericService;
try {
genericService = configCache.get(reference);
if (Objects.isNull(genericService)) {
configCache.destroy(reference);
throw new RuntimeException("dubbo genericService has exception");
}
} catch (NullPointerException e) {
configCache.destroy(reference);
log.error("DubboProxyService genericInvoker configCache fail, paramMap={}, cause={}", paramMap, Throwables.getStackTraceAsString(e));
throw new RuntimeException(e.getMessage());
}
Pair<String[], Object[]> pair = buildParameter(paramMap);
try {
//log.info(JsonUtils.toJson(paramMap));
return genericService.$invoke(paramMap.get(Constants.DUBBO_METHOD).toString(), pair.getLeft(), pair.getRight());
} catch (GenericException e) {
log.error("DubboProxyService genericInvoker $invoke fail, paramMap={}, cause={}", paramMap, Throwables.getStackTraceAsString(e));
throw new RuntimeException(e.getMessage());
}
}
private ReferenceConfig<GenericService> buildReferenceConfig(DubboSelectorHandle selectorHandle, DubboRuleHandler ruleHandler, String interfaceName) {
String appName = selectorHandle.getAppName();
ReferenceConfig<GenericService> reference = new ReferenceConfig<>();
reference.setGeneric(true);
reference.setApplication(APPLICATION_CONFIG_MAP.computeIfAbsent(appName, f -> new ApplicationConfig(appName)));
reference.setRegistries(REGISTRY_CONFIG_MAP.computeIfAbsent(appName,
f -> StreamSupport.stream(Optional.of(selectorHandle.getRegistry())
.map(DUBBO_REGISTRIES_SPLITTER::split)
.get().spliterator(), false)
.map(s -> "zookeeper://" + s)
.map(RegistryConfig::new)
.collect(Collectors.toList())));
reference.setInterface(interfaceName);
Optional.ofNullable(ruleHandler).map(DubboRuleHandler::getTimeout).ifPresent(reference::setTimeout);
Optional.ofNullable(ruleHandler).map(DubboRuleHandler::getRetries).ifPresent(reference::setRetries);
Optional.of(selectorHandle).map(DubboSelectorHandle::getProtocol).ifPresent(s -> {
if (!Strings.isNullOrEmpty(s)) {
reference.setProtocol(s);
}
});
Optional.ofNullable(ruleHandler).map(DubboRuleHandler::getVersion).ifPresent(s -> {
if (!Strings.isNullOrEmpty(s)) {
reference.setVersion(s);
}
});
Optional.ofNullable(ruleHandler).map(DubboRuleHandler::getGroup).ifPresent(s -> {
if (!Strings.isNullOrEmpty(s)) {
reference.setGroup(s);
}
});
Optional.ofNullable(ruleHandler).map(DubboRuleHandler::getLoadBalance).ifPresent(s -> {
if (DUBBO_LOADBALANCE_LIST.contains(s)) {
reference.setLoadbalance(s);
}
});
//reference.setCluster("issFailover");
reference.setClient("netty4");
return reference;
}
private Pair<String[], Object[]> buildParameter(Map<String, Object> paramMap) {
List<String> parameterTypes = new ArrayList<>();
List<Object> args = new ArrayList<>();
if (paramMap.containsKey(Constants.DUBBO_PARAM_CLASS)) {
List<String> clazz = GsonUtils.getInstance().fromList(paramMap.get(Constants.DUBBO_PARAM_CLASS).toString(), String.class);
AtomicBoolean hasList = new AtomicBoolean(false);
clazz.forEach(c -> {
parameterTypes.add(c);
if (List.class.getName().equals(c)) {
hasList.set(true);
}
});
if (hasList.get()) {
String classParams = paramMap.get(Constants.DUBBO_CLASS_PARAMS).toString();
List<Map> params = GsonUtils.getInstance().toListMap(classParams);
args.add(params);
} else {
String classParams = paramMap.get(Constants.DUBBO_CLASS_PARAMS).toString();
args.addAll(GsonUtils.getInstance().fromJson(classParams, List.class));
}
}
if (paramMap.containsKey(Constants.DUBBO_GENERIC_PARAMS) && !"null".equals(paramMap.get(Constants.DUBBO_GENERIC_PARAMS).toString())) {
Map<String, Object> map = GsonUtils.getInstance().toObjectMap(paramMap.get(Constants.DUBBO_GENERIC_PARAMS).toString());
map.forEach((k, v) -> {
if (v instanceof JsonArray) {
List<String> arg = GsonUtils.getInstance().fromList(v.toString(), String.class);
arg.forEach(a -> {
parameterTypes.add(k);
args.add(a);
});
} else {
parameterTypes.add(k);
args.add(v);
}
});
}
return Pair.of(parameterTypes.toArray(new String[0]), args.toArray());
}
}
dubbo 2.7.4.1进行泛化同步调用时,性能不弱于2.6.2
dubbo 2.7.4.1 进行泛化同步调用时,性能大副弱于2.6.2
If there is an exception, please attach the exception trace:
Just put your stack trace here!
2.7.5 is expected to have significant performance improve and will be released soon.
Do we have the plan when 2.7.5 will release?
最近也碰到这个问题,最近内部API网关升级dubbo到2.7.4.1,cpu使用占比很高,分享下排查总结。
(1)2.7.4.1版本的ReferenceConfig.get方法,会调用checkAndUpdateSubConfigs方法,代码:https://github.com/apache/dubbo/blob/dubbo-2.7.4.1/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
(2)2.7.6版本,ReferenceConfig.get方法不再调用checkAndUpdateSubConfigs,放到init方法执行,内部应该是优化调整元数据的更新&校验逻辑。
升级到2.7.6版本后,问题解决
附:
dubbo2.6.6:

dubbo2.7.4.1:

dubbo2.7.6:

Most helpful comment
2.7.5 is expected to have significant performance improve and will be released soon.