use of com.tencent.polaris.api.plugin.route.RouteResult in project polaris-java by polarismesh.
the class BaseFlow method processRouterChain.
private static boolean processRouterChain(List<ServiceRouter> routers, RouteInfo routeInfo, ServiceInstancesWrap serviceInstances) throws PolarisException {
if (CollectionUtils.isEmpty(routers)) {
return false;
}
boolean processed = false;
for (ServiceRouter router : routers) {
if (CollectionUtils.isEmpty(serviceInstances.getInstances())) {
// 实例为空,则退出路由
break;
}
if (!router.enable(routeInfo, serviceInstances)) {
continue;
}
processed = true;
do {
RouteResult filteredInstances = router.getFilteredInstances(routeInfo, serviceInstances);
RouteResult.NextRouterInfo nextRouterInfo = filteredInstances.getNextRouterInfo();
if (nextRouterInfo.getState() == RouteResult.State.Next) {
serviceInstances.setInstances(filteredInstances.getInstances());
break;
}
// 重试获取
routeInfo.setNextRouterInfo(nextRouterInfo);
} while (true);
}
return processed;
}
use of com.tencent.polaris.api.plugin.route.RouteResult in project polaris-java by polarismesh.
the class MetadataRouter method router.
@Override
public RouteResult router(RouteInfo routeInfo, ServiceInstances instances) throws PolarisException {
FailOverType failOverType = config.getMetadataFailOverType();
Map<String, String> svcMetadata = instances.getMetadata();
if (MapUtils.isNotEmpty(svcMetadata)) {
if (svcMetadata.containsKey(KEY_METADATA_FAILOVER_TYPE)) {
String value = svcMetadata.get(KEY_METADATA_FAILOVER_TYPE);
if (valueToFailoverType.containsKey(value)) {
failOverType = valueToFailoverType.get(value);
}
}
}
MetadataFailoverType metadataFailoverType = routeInfo.getMetadataFailoverType();
if (null != metadataFailoverType) {
failOverType = inputToFailoverType.get(metadataFailoverType);
}
boolean availableInsFlag;
Map<String, String> reqMetadata = routeInfo.getDestService().getMetadata();
List<Instance> instanceList = new ArrayList<>();
for (Instance ins : instances.getInstances()) {
availableInsFlag = true;
// 要满足请求中的metadata K-V全部存在于实例的metadata中
for (Map.Entry<String, String> entry : reqMetadata.entrySet()) {
if (ins.getMetadata().containsKey(entry.getKey()) && ins.getMetadata().get(entry.getKey()).equals(entry.getValue())) {
continue;
}
availableInsFlag = false;
break;
}
if (availableInsFlag) {
instanceList.add(ins);
}
}
if (!CollectionUtils.isEmpty(instanceList)) {
return new RouteResult(instanceList, RouteResult.State.Next);
}
switch(failOverType) {
case all:
return new RouteResult(instances.getInstances(), RouteResult.State.Next);
case others:
return new RouteResult(addNotContainKeyIns(instances, reqMetadata), RouteResult.State.Next);
default:
// 默认不降级
throw new PolarisException(ErrorCode.METADATA_MISMATCH, String.format("can not find any instance by service %s", routeInfo.getDestService()));
}
}
use of com.tencent.polaris.api.plugin.route.RouteResult in project polaris-java by polarismesh.
the class NearbyRouter method router.
@Override
public RouteResult router(RouteInfo routeInfo, ServiceInstances serviceInstances) throws PolarisException {
// 先获取最低可用就近级别
LocationLevel minAvailableLevel = config.getMatchLevel();
if (null == minAvailableLevel) {
minAvailableLevel = defaultMinLevel;
}
LocationLevel minLevel = minAvailableLevel;
if (null != routeInfo.getNextRouterInfo()) {
if (null != routeInfo.getNextRouterInfo().getLocationLevel()) {
minLevel = routeInfo.getNextRouterInfo().getLocationLevel();
}
if (null != routeInfo.getNextRouterInfo().getMinAvailableLevel()) {
minAvailableLevel = routeInfo.getNextRouterInfo().getMinAvailableLevel();
}
}
LocationLevel maxLevel = config.getMaxMatchLevel();
if (null == maxLevel) {
maxLevel = LocationLevel.all;
}
Map<LocationLevel, String> clientLocationInfo = locationInfo.get();
if (minLevel.ordinal() >= maxLevel.ordinal()) {
List<Instance> instances = selectInstances(serviceInstances, minAvailableLevel, clientLocationInfo);
if (CollectionUtils.isEmpty(instances)) {
throw new PolarisException(ErrorCode.LOCATION_MISMATCH, String.format("can not find any instance by level %s", minLevel.name()));
}
// 已经循环了一圈
return new RouteResult(selectInstances(serviceInstances, minAvailableLevel, clientLocationInfo), RouteResult.State.Next);
}
CheckResult checkResult = new CheckResult();
for (int i = minLevel.ordinal(); i <= maxLevel.ordinal(); i++) {
LocationLevel curLevel = LocationLevel.values()[i];
checkResult = hasHealthyInstances(serviceInstances, routeInfo.getStatusDimensions(), curLevel, clientLocationInfo);
checkResult.curLevel = curLevel;
if (!CollectionUtils.isEmpty(checkResult.instances)) {
break;
} else {
minAvailableLevel = curLevel;
}
}
if (CollectionUtils.isEmpty(checkResult.instances)) {
throw new PolarisException(ErrorCode.LOCATION_MISMATCH, String.format("can not find any instance by level %s", checkResult.curLevel.name()));
}
if (!config.isEnableDegradeByUnhealthyPercent() || checkResult.curLevel == LocationLevel.all) {
return new RouteResult(checkResult.instances, RouteResult.State.Next);
}
int healthyInstanceCount = checkResult.healthyInstanceCount;
double actualHealthyPercent = (double) healthyInstanceCount / (double) serviceInstances.getInstances().size();
if (actualHealthyPercent <= healthyPercentToDegrade) {
LOG.debug("[shouldDegrade] enableDegradeByUnhealthyPercent = {},unhealthyPercentToDegrade={}," + "healthyPercent={},isStrict={},matchLevel={}", config.isEnableDegradeByUnhealthyPercent(), config.getUnhealthyPercentToDegrade(), actualHealthyPercent, config.isStrictNearby(), checkResult.curLevel);
RouteResult result = new RouteResult(checkResult.instances, RouteResult.State.Retry);
result.getNextRouterInfo().setLocationLevel(nextLevel(checkResult.curLevel));
result.getNextRouterInfo().setMinAvailableLevel(minAvailableLevel);
return result;
}
return new RouteResult(checkResult.instances, RouteResult.State.Next);
}
Aggregations