Commit a725760b by Nepxion

增加基于Region的权重流量策略

parent 2f006b39
package com.nepxion.discovery.common.entity;
/**
* <p>Title: Nepxion Discovery</p>
* <p>Description: Nepxion Discovery</p>
* <p>Copyright: Copyright (c) 2017-2050</p>
* <p>Company: Nepxion</p>
* @author Haojun Ren
* @version 1.0
*/
import java.io.Serializable;
import java.util.Map;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
public class RegionWeightEntity implements Serializable {
private static final long serialVersionUID = 3356648245119125011L;
private Map<String, Integer> weightMap;
public Map<String, Integer> getWeightMap() {
return weightMap;
}
public void setWeightMap(Map<String, Integer> weightMap) {
this.weightMap = weightMap;
}
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
@Override
public boolean equals(Object object) {
return EqualsBuilder.reflectionEquals(this, object);
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}
}
\ No newline at end of file
...@@ -14,6 +14,7 @@ import java.util.LinkedHashMap; ...@@ -14,6 +14,7 @@ import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
...@@ -23,6 +24,7 @@ public class WeightFilterEntity implements Serializable { ...@@ -23,6 +24,7 @@ public class WeightFilterEntity implements Serializable {
private static final long serialVersionUID = 7313443273653189837L; private static final long serialVersionUID = 7313443273653189837L;
private Map<String, List<WeightEntity>> weightEntityMap = new LinkedHashMap<String, List<WeightEntity>>(); private Map<String, List<WeightEntity>> weightEntityMap = new LinkedHashMap<String, List<WeightEntity>>();
private RegionWeightEntity regionWeightEntity;
public Map<String, List<WeightEntity>> getWeightEntityMap() { public Map<String, List<WeightEntity>> getWeightEntityMap() {
return weightEntityMap; return weightEntityMap;
...@@ -32,6 +34,18 @@ public class WeightFilterEntity implements Serializable { ...@@ -32,6 +34,18 @@ public class WeightFilterEntity implements Serializable {
this.weightEntityMap = weightEntityMap; this.weightEntityMap = weightEntityMap;
} }
public RegionWeightEntity getRegionWeightEntity() {
return regionWeightEntity;
}
public void setRegionWeightEntity(RegionWeightEntity regionWeightEntity) {
this.regionWeightEntity = regionWeightEntity;
}
public boolean hasWeight() {
return MapUtils.isNotEmpty(weightEntityMap) || regionWeightEntity != null;
}
@Override @Override
public int hashCode() { public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this); return HashCodeBuilder.reflectionHashCode(this);
......
...@@ -9,20 +9,43 @@ package com.nepxion.discovery.common.util; ...@@ -9,20 +9,43 @@ package com.nepxion.discovery.common.util;
* @version 1.0 * @version 1.0
*/ */
import java.io.IOException;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
public class JsonUtil { public class JsonUtil {
private static ObjectMapper objectMapper; private static ObjectMapper objectMapper;
static { static {
objectMapper = new ObjectMapper(); objectMapper = new ObjectMapper();
// objectMapper.getSerializerProvider().setNullKeySerializer(new NullKeySerializer());
// objectMapper.setDateFormat(new SimpleDateFormat(DiscoveryConstant.DATE_FORMAT)); // objectMapper.setDateFormat(new SimpleDateFormat(DiscoveryConstant.DATE_FORMAT));
} }
public static class NullKeySerializer extends StdSerializer<Object> {
private static final long serialVersionUID = -9176767187240330396L;
public NullKeySerializer() {
this(null);
}
public NullKeySerializer(Class<Object> object) {
super(object);
}
@Override
public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeFieldName(StringUtils.EMPTY);
}
}
public static <T> String toJson(T object) { public static <T> String toJson(T object) {
if (object == null) { if (object == null) {
throw new IllegalArgumentException("Object is null"); throw new IllegalArgumentException("Object is null");
......
...@@ -40,6 +40,7 @@ import com.fasterxml.jackson.core.type.TypeReference; ...@@ -40,6 +40,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
import com.nepxion.discovery.common.constant.DiscoveryConstant; import com.nepxion.discovery.common.constant.DiscoveryConstant;
import com.nepxion.discovery.common.entity.CustomizationEntity; import com.nepxion.discovery.common.entity.CustomizationEntity;
import com.nepxion.discovery.common.entity.DiscoveryEntity; import com.nepxion.discovery.common.entity.DiscoveryEntity;
import com.nepxion.discovery.common.entity.RegionWeightEntity;
import com.nepxion.discovery.common.entity.RouterEntity; import com.nepxion.discovery.common.entity.RouterEntity;
import com.nepxion.discovery.common.entity.RuleEntity; import com.nepxion.discovery.common.entity.RuleEntity;
import com.nepxion.discovery.common.entity.WeightEntity; import com.nepxion.discovery.common.entity.WeightEntity;
...@@ -126,7 +127,7 @@ public class RouterEndpoint { ...@@ -126,7 +127,7 @@ public class RouterEndpoint {
String region = pluginAdapter.getRegion(); String region = pluginAdapter.getRegion();
String host = pluginAdapter.getHost(); String host = pluginAdapter.getHost();
int port = pluginAdapter.getPort(); int port = pluginAdapter.getPort();
int weight = getWeight(serviceId, version); int weight = getWeight(serviceId, version, region);
Map<String, String> customMap = getCustomMap(serviceId); Map<String, String> customMap = getCustomMap(serviceId);
String contextPath = pluginAdapter.getContextPath(); String contextPath = pluginAdapter.getContextPath();
...@@ -164,7 +165,7 @@ public class RouterEndpoint { ...@@ -164,7 +165,7 @@ public class RouterEndpoint {
String region = metadata.get(DiscoveryConstant.REGION); String region = metadata.get(DiscoveryConstant.REGION);
String host = instance.getHost(); String host = instance.getHost();
int port = instance.getPort(); int port = instance.getPort();
int weight = getWeight(routeServiceId, version); int weight = getWeight(routeServiceId, version, region);
Map<String, String> customMap = getCustomMap(serviceId); Map<String, String> customMap = getCustomMap(serviceId);
String contextPath = metadata.get(DiscoveryConstant.SPRING_APPLICATION_CONTEXT_PATH); String contextPath = metadata.get(DiscoveryConstant.SPRING_APPLICATION_CONTEXT_PATH);
...@@ -270,7 +271,7 @@ public class RouterEndpoint { ...@@ -270,7 +271,7 @@ public class RouterEndpoint {
return routerEntityList; return routerEntityList;
} }
private int getWeight(String providerServiceId, String providerVersion) { private int getWeight(String providerServiceId, String providerVersion, String providerRegion) {
RuleEntity ruleEntity = pluginAdapter.getRule(); RuleEntity ruleEntity = pluginAdapter.getRule();
if (ruleEntity == null) { if (ruleEntity == null) {
return -1; return -1;
...@@ -286,23 +287,35 @@ public class RouterEndpoint { ...@@ -286,23 +287,35 @@ public class RouterEndpoint {
return -1; return -1;
} }
Map<String, List<WeightEntity>> weightEntityMap = weightFilterEntity.getWeightEntityMap(); if (!weightFilterEntity.hasWeight()) {
if (MapUtils.isEmpty(weightEntityMap)) {
return -1; return -1;
} }
Map<String, List<WeightEntity>> weightEntityMap = weightFilterEntity.getWeightEntityMap();
RegionWeightEntity regionWeightEntity = weightFilterEntity.getRegionWeightEntity();
String serviceId = pluginAdapter.getServiceId(); String serviceId = pluginAdapter.getServiceId();
// 取局部的权重配置 // 取局部的权重配置
int weight = getWeight(serviceId, providerServiceId, providerVersion, weightEntityMap); int weight = getWeight(serviceId, providerServiceId, providerVersion, weightEntityMap);
// 局部权重配置没找到,取全局的权重配置 // 局部权重配置没找到,取全局的权重配置
if (weight < 0) { if (weight < 0) {
weight = getWeight(null, providerServiceId, providerVersion, weightEntityMap); weight = getWeight(StringUtils.EMPTY, providerServiceId, providerVersion, weightEntityMap);
}
// 全局的权重配置没找到,取区域的权重配置
if (weight < 0) {
weight = getWeight(providerRegion, regionWeightEntity);
} }
return weight; return weight;
} }
private int getWeight(String consumerServiceId, String providerServiceId, String providerVersion, Map<String, List<WeightEntity>> weightEntityMap) { private int getWeight(String consumerServiceId, String providerServiceId, String providerVersion, Map<String, List<WeightEntity>> weightEntityMap) {
if (MapUtils.isEmpty(weightEntityMap)) {
return -1;
}
List<WeightEntity> weightEntityList = weightEntityMap.get(consumerServiceId); List<WeightEntity> weightEntityList = weightEntityMap.get(consumerServiceId);
if (CollectionUtils.isEmpty(weightEntityList)) { if (CollectionUtils.isEmpty(weightEntityList)) {
return -1; return -1;
...@@ -312,6 +325,10 @@ public class RouterEndpoint { ...@@ -312,6 +325,10 @@ public class RouterEndpoint {
String providerServiceName = weightEntity.getProviderServiceName(); String providerServiceName = weightEntity.getProviderServiceName();
if (StringUtils.equalsIgnoreCase(providerServiceName, providerServiceId)) { if (StringUtils.equalsIgnoreCase(providerServiceName, providerServiceId)) {
Map<String, Integer> weightMap = weightEntity.getWeightMap(); Map<String, Integer> weightMap = weightEntity.getWeightMap();
if (MapUtils.isEmpty(weightMap)) {
return -1;
}
Integer weight = weightMap.get(providerVersion); Integer weight = weightMap.get(providerVersion);
if (weight != null) { if (weight != null) {
return weight; return weight;
...@@ -324,6 +341,28 @@ public class RouterEndpoint { ...@@ -324,6 +341,28 @@ public class RouterEndpoint {
return -1; return -1;
} }
private int getWeight(String providerRegion, RegionWeightEntity regionWeightEntity) {
if (StringUtils.isEmpty(providerRegion)) {
return -1;
}
if (regionWeightEntity == null) {
return -1;
}
Map<String, Integer> weightMap = regionWeightEntity.getWeightMap();
if (MapUtils.isEmpty(weightMap)) {
return -1;
}
Integer weight = weightMap.get(providerRegion);
if (weight != null) {
return weight;
} else {
return -1;
}
}
private Map<String, String> getCustomMap(String serviceId) { private Map<String, String> getCustomMap(String serviceId) {
RuleEntity ruleEntity = pluginAdapter.getRule(); RuleEntity ruleEntity = pluginAdapter.getRule();
if (ruleEntity == null) { if (ruleEntity == null) {
......
...@@ -15,6 +15,7 @@ public class ConfigConstant { ...@@ -15,6 +15,7 @@ public class ConfigConstant {
public static final String DISCOVERY_ELEMENT_NAME = "discovery"; public static final String DISCOVERY_ELEMENT_NAME = "discovery";
public static final String CUSTOMIZATION_ELEMENT_NAME = "customization"; public static final String CUSTOMIZATION_ELEMENT_NAME = "customization";
public static final String SERVICE_ELEMENT_NAME = "service"; public static final String SERVICE_ELEMENT_NAME = "service";
public static final String REGION_ELEMENT_NAME = "region";
public static final String BLACKLIST_ELEMENT_NAME = "blacklist"; public static final String BLACKLIST_ELEMENT_NAME = "blacklist";
public static final String WHITELIST_ELEMENT_NAME = "whitelist"; public static final String WHITELIST_ELEMENT_NAME = "whitelist";
public static final String COUNT_ELEMENT_NAME = "count"; public static final String COUNT_ELEMENT_NAME = "count";
......
...@@ -30,6 +30,7 @@ import com.nepxion.discovery.common.entity.DiscoveryEntity; ...@@ -30,6 +30,7 @@ import com.nepxion.discovery.common.entity.DiscoveryEntity;
import com.nepxion.discovery.common.entity.FilterHolderEntity; import com.nepxion.discovery.common.entity.FilterHolderEntity;
import com.nepxion.discovery.common.entity.FilterType; import com.nepxion.discovery.common.entity.FilterType;
import com.nepxion.discovery.common.entity.HostFilterEntity; import com.nepxion.discovery.common.entity.HostFilterEntity;
import com.nepxion.discovery.common.entity.RegionWeightEntity;
import com.nepxion.discovery.common.entity.RegisterEntity; import com.nepxion.discovery.common.entity.RegisterEntity;
import com.nepxion.discovery.common.entity.RuleEntity; import com.nepxion.discovery.common.entity.RuleEntity;
import com.nepxion.discovery.common.entity.VersionEntity; import com.nepxion.discovery.common.entity.VersionEntity;
...@@ -371,8 +372,10 @@ public class XmlConfigParser implements PluginConfigParser { ...@@ -371,8 +372,10 @@ public class XmlConfigParser implements PluginConfigParser {
String consumerServiceName = null; String consumerServiceName = null;
if (consumerServiceNameAttribute != null) { if (consumerServiceNameAttribute != null) {
consumerServiceName = consumerServiceNameAttribute.getData().toString().trim(); consumerServiceName = consumerServiceNameAttribute.getData().toString().trim();
weightEntity.setConsumerServiceName(consumerServiceName); } else {
consumerServiceName = StringUtils.EMPTY;
} }
weightEntity.setConsumerServiceName(consumerServiceName);
Attribute providerServiceNameAttribute = childElement.attribute(ConfigConstant.PROVIDER_SERVICE_NAME_ATTRIBUTE_NAME); Attribute providerServiceNameAttribute = childElement.attribute(ConfigConstant.PROVIDER_SERVICE_NAME_ATTRIBUTE_NAME);
if (providerServiceNameAttribute == null) { if (providerServiceNameAttribute == null) {
...@@ -407,6 +410,34 @@ public class XmlConfigParser implements PluginConfigParser { ...@@ -407,6 +410,34 @@ public class XmlConfigParser implements PluginConfigParser {
} }
weightEntityList.add(weightEntity); weightEntityList.add(weightEntity);
} else if (StringUtils.equals(childElement.getName(), ConfigConstant.REGION_ELEMENT_NAME)) {
RegionWeightEntity regionWeightEntity = weightFilterEntity.getRegionWeightEntity();
if (regionWeightEntity != null) {
throw new DiscoveryException("Allow only one element[" + ConfigConstant.REGION_ELEMENT_NAME + "] to be configed");
}
regionWeightEntity = new RegionWeightEntity();
Attribute providerWeightValueAttribute = childElement.attribute(ConfigConstant.PROVIDER_WEIGHT_VALUE_ATTRIBUTE_NAME);
if (providerWeightValueAttribute == null) {
throw new DiscoveryException("Attribute[" + ConfigConstant.PROVIDER_WEIGHT_VALUE_ATTRIBUTE_NAME + "] in element[" + childElement.getName() + "] is missing");
}
String providerWeightValue = providerWeightValueAttribute.getData().toString().trim();
Map<String, Integer> weightMap = new LinkedHashMap<String, Integer>();
List<String> providerWeightValueList = parseList(providerWeightValue);
for (String value : providerWeightValueList) {
String[] valueArray = StringUtils.split(value, ConfigConstant.SEPARATE);
String region = valueArray[0].trim();
int weight = Integer.valueOf(valueArray[1].trim());
if (weight < 0) {
throw new DiscoveryException("Attribute[" + ConfigConstant.PROVIDER_WEIGHT_VALUE_ATTRIBUTE_NAME + "] in element[" + childElement.getName() + "] has weight value less than 0");
}
weightMap.put(region, weight);
}
regionWeightEntity.setWeightMap(weightMap);
weightFilterEntity.setRegionWeightEntity(regionWeightEntity);
} }
} }
} }
......
...@@ -151,4 +151,9 @@ public abstract class AbstractPluginAdapter implements PluginAdapter { ...@@ -151,4 +151,9 @@ public abstract class AbstractPluginAdapter implements PluginAdapter {
public String getServerVersion(Server server) { public String getServerVersion(Server server) {
return getServerMetadata(server).get(DiscoveryConstant.VERSION); return getServerMetadata(server).get(DiscoveryConstant.VERSION);
} }
@Override
public String getServerRegion(Server server) {
return getServerMetadata(server).get(DiscoveryConstant.REGION);
}
} }
\ No newline at end of file
...@@ -54,4 +54,6 @@ public interface PluginAdapter { ...@@ -54,4 +54,6 @@ public interface PluginAdapter {
Map<String, String> getServerMetadata(Server server); Map<String, String> getServerMetadata(Server server);
String getServerVersion(Server server); String getServerVersion(Server server);
String getServerRegion(Server server);
} }
\ No newline at end of file
...@@ -10,14 +10,12 @@ package com.nepxion.discovery.plugin.framework.decorator; ...@@ -10,14 +10,12 @@ package com.nepxion.discovery.plugin.framework.decorator;
*/ */
import java.util.List; import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import com.nepxion.discovery.common.entity.WeightEntity; import com.nepxion.discovery.common.entity.WeightFilterEntity;
import com.nepxion.discovery.plugin.framework.adapter.PluginAdapter; import com.nepxion.discovery.plugin.framework.adapter.PluginAdapter;
import com.nepxion.discovery.plugin.framework.loadbalance.WeightRandomLoadBalance; import com.nepxion.discovery.plugin.framework.loadbalance.WeightRandomLoadBalance;
import com.netflix.loadbalancer.PredicateBasedRule; import com.netflix.loadbalancer.PredicateBasedRule;
...@@ -37,15 +35,15 @@ public abstract class PredicateBasedRuleDecorator extends PredicateBasedRule { ...@@ -37,15 +35,15 @@ public abstract class PredicateBasedRuleDecorator extends PredicateBasedRule {
@Override @Override
public Server choose(Object key) { public Server choose(Object key) {
Map<String, List<WeightEntity>> weightEntityMap = weightRandomLoadBalance.getWeightEntityMap(); WeightFilterEntity weightFilterEntity = weightRandomLoadBalance.getWeightFilterEntity();
if (MapUtils.isEmpty(weightEntityMap)) { if (!weightFilterEntity.hasWeight()) {
return super.choose(key); return super.choose(key);
} }
List<Server> eligibleServers = getPredicate().getEligibleServers(getLoadBalancer().getAllServers(), key); List<Server> eligibleServers = getPredicate().getEligibleServers(getLoadBalancer().getAllServers(), key);
try { try {
return weightRandomLoadBalance.choose(eligibleServers, weightEntityMap); return weightRandomLoadBalance.choose(eligibleServers, weightFilterEntity);
} catch (Exception e) { } catch (Exception e) {
return super.choose(key); return super.choose(key);
} }
......
...@@ -10,14 +10,12 @@ package com.nepxion.discovery.plugin.framework.decorator; ...@@ -10,14 +10,12 @@ package com.nepxion.discovery.plugin.framework.decorator;
*/ */
import java.util.List; import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import com.nepxion.discovery.common.entity.WeightEntity; import com.nepxion.discovery.common.entity.WeightFilterEntity;
import com.nepxion.discovery.plugin.framework.adapter.PluginAdapter; import com.nepxion.discovery.plugin.framework.adapter.PluginAdapter;
import com.nepxion.discovery.plugin.framework.loadbalance.WeightRandomLoadBalance; import com.nepxion.discovery.plugin.framework.loadbalance.WeightRandomLoadBalance;
import com.netflix.loadbalancer.Server; import com.netflix.loadbalancer.Server;
...@@ -37,15 +35,15 @@ public class ZoneAvoidanceRuleDecorator extends ZoneAvoidanceRule { ...@@ -37,15 +35,15 @@ public class ZoneAvoidanceRuleDecorator extends ZoneAvoidanceRule {
@Override @Override
public Server choose(Object key) { public Server choose(Object key) {
Map<String, List<WeightEntity>> weightEntityMap = weightRandomLoadBalance.getWeightEntityMap(); WeightFilterEntity weightFilterEntity = weightRandomLoadBalance.getWeightFilterEntity();
if (MapUtils.isEmpty(weightEntityMap)) { if (!weightFilterEntity.hasWeight()) {
return super.choose(key); return super.choose(key);
} }
List<Server> eligibleServers = getPredicate().getEligibleServers(getLoadBalancer().getAllServers(), key); List<Server> eligibleServers = getPredicate().getEligibleServers(getLoadBalancer().getAllServers(), key);
try { try {
return weightRandomLoadBalance.choose(eligibleServers, weightEntityMap); return weightRandomLoadBalance.choose(eligibleServers, weightFilterEntity);
} catch (Exception e) { } catch (Exception e) {
return super.choose(key); return super.choose(key);
} }
......
...@@ -18,6 +18,7 @@ import org.apache.commons.collections4.MapUtils; ...@@ -18,6 +18,7 @@ import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import com.nepxion.discovery.common.entity.DiscoveryEntity; import com.nepxion.discovery.common.entity.DiscoveryEntity;
import com.nepxion.discovery.common.entity.RegionWeightEntity;
import com.nepxion.discovery.common.entity.RuleEntity; import com.nepxion.discovery.common.entity.RuleEntity;
import com.nepxion.discovery.common.entity.WeightEntity; import com.nepxion.discovery.common.entity.WeightEntity;
import com.nepxion.discovery.common.entity.WeightFilterEntity; import com.nepxion.discovery.common.entity.WeightFilterEntity;
...@@ -28,7 +29,7 @@ import com.netflix.loadbalancer.Server; ...@@ -28,7 +29,7 @@ import com.netflix.loadbalancer.Server;
public class WeightRandomLoadBalance { public class WeightRandomLoadBalance {
private PluginAdapter pluginAdapter; private PluginAdapter pluginAdapter;
public Map<String, List<WeightEntity>> getWeightEntityMap() { public WeightFilterEntity getWeightFilterEntity() {
RuleEntity ruleEntity = pluginAdapter.getRule(); RuleEntity ruleEntity = pluginAdapter.getRule();
if (ruleEntity == null) { if (ruleEntity == null) {
return null; return null;
...@@ -40,19 +41,11 @@ public class WeightRandomLoadBalance { ...@@ -40,19 +41,11 @@ public class WeightRandomLoadBalance {
} }
WeightFilterEntity weightFilterEntity = discoveryEntity.getWeightFilterEntity(); WeightFilterEntity weightFilterEntity = discoveryEntity.getWeightFilterEntity();
if (weightFilterEntity == null) {
return null;
}
Map<String, List<WeightEntity>> weightEntityMap = weightFilterEntity.getWeightEntityMap(); return weightFilterEntity;
if (MapUtils.isEmpty(weightEntityMap)) {
return null;
} }
return weightEntityMap; public Server choose(List<Server> serverList, WeightFilterEntity weightFilterEntity) {
}
public Server choose(List<Server> serverList, Map<String, List<WeightEntity>> weightEntityMap) {
if (CollectionUtils.isEmpty(serverList)) { if (CollectionUtils.isEmpty(serverList)) {
return null; return null;
} }
...@@ -60,7 +53,7 @@ public class WeightRandomLoadBalance { ...@@ -60,7 +53,7 @@ public class WeightRandomLoadBalance {
int[] weights = new int[serverList.size()]; int[] weights = new int[serverList.size()];
for (int i = 0; i < serverList.size(); i++) { for (int i = 0; i < serverList.size(); i++) {
Server server = serverList.get(i); Server server = serverList.get(i);
int weight = getWeight(server, weightEntityMap); int weight = getWeight(server, weightFilterEntity);
if (weight > 0) { if (weight > 0) {
weights[i] = weight; weights[i] = weight;
} }
...@@ -99,26 +92,40 @@ public class WeightRandomLoadBalance { ...@@ -99,26 +92,40 @@ public class WeightRandomLoadBalance {
return weightHolder[0][0]; return weightHolder[0][0];
} }
private int getWeight(Server server, Map<String, List<WeightEntity>> weightEntityMap) { private int getWeight(Server server, WeightFilterEntity weightFilterEntity) {
Map<String, List<WeightEntity>> weightEntityMap = weightFilterEntity.getWeightEntityMap();
RegionWeightEntity regionWeightEntity = weightFilterEntity.getRegionWeightEntity();
String providerServiceId = server.getMetaInfo().getAppName(); String providerServiceId = server.getMetaInfo().getAppName();
String providerVersion = pluginAdapter.getServerVersion(server); String providerVersion = pluginAdapter.getServerVersion(server);
String providerRegion = pluginAdapter.getServerRegion(server);
String serviceId = pluginAdapter.getServiceId(); String serviceId = pluginAdapter.getServiceId();
// 取局部的权重配置 // 取局部的权重配置
int weight = getWeight(serviceId, providerServiceId, providerVersion, weightEntityMap); int weight = getWeight(serviceId, providerServiceId, providerVersion, weightEntityMap);
// 局部权重配置没找到,取全局的权重配置 // 局部权重配置没找到,取全局的权重配置
if (weight < 0) { if (weight < 0) {
weight = getWeight(null, providerServiceId, providerVersion, weightEntityMap); weight = getWeight(StringUtils.EMPTY, providerServiceId, providerVersion, weightEntityMap);
} }
// 全局的权重配置没找到,取区域的权重配置
if (weight < 0) { if (weight < 0) {
throw new DiscoveryException("Weight isn't configed for serviceId=" + providerServiceId + ", version=" + providerVersion); weight = getWeight(providerRegion, regionWeightEntity);
}
if (weight < 0) {
throw new DiscoveryException("Weight isn't configed for serviceId=" + providerServiceId);
} }
return weight; return weight;
} }
private int getWeight(String consumerServiceId, String providerServiceId, String providerVersion, Map<String, List<WeightEntity>> weightEntityMap) { private int getWeight(String consumerServiceId, String providerServiceId, String providerVersion, Map<String, List<WeightEntity>> weightEntityMap) {
if (MapUtils.isEmpty(weightEntityMap)) {
return -1;
}
List<WeightEntity> weightEntityList = weightEntityMap.get(consumerServiceId); List<WeightEntity> weightEntityList = weightEntityMap.get(consumerServiceId);
if (CollectionUtils.isEmpty(weightEntityList)) { if (CollectionUtils.isEmpty(weightEntityList)) {
return -1; return -1;
...@@ -128,6 +135,10 @@ public class WeightRandomLoadBalance { ...@@ -128,6 +135,10 @@ public class WeightRandomLoadBalance {
String providerServiceName = weightEntity.getProviderServiceName(); String providerServiceName = weightEntity.getProviderServiceName();
if (StringUtils.equalsIgnoreCase(providerServiceName, providerServiceId)) { if (StringUtils.equalsIgnoreCase(providerServiceName, providerServiceId)) {
Map<String, Integer> weightMap = weightEntity.getWeightMap(); Map<String, Integer> weightMap = weightEntity.getWeightMap();
if (MapUtils.isEmpty(weightMap)) {
return -1;
}
Integer weight = weightMap.get(providerVersion); Integer weight = weightMap.get(providerVersion);
if (weight != null) { if (weight != null) {
return weight; return weight;
...@@ -140,6 +151,28 @@ public class WeightRandomLoadBalance { ...@@ -140,6 +151,28 @@ public class WeightRandomLoadBalance {
return -1; return -1;
} }
private int getWeight(String providerRegion, RegionWeightEntity regionWeightEntity) {
if (StringUtils.isEmpty(providerRegion)) {
return -1;
}
if (regionWeightEntity == null) {
return -1;
}
Map<String, Integer> weightMap = regionWeightEntity.getWeightMap();
if (MapUtils.isEmpty(weightMap)) {
return -1;
}
Integer weight = weightMap.get(providerRegion);
if (weight != null) {
return weight;
} else {
return -1;
}
}
public void setPluginAdapter(PluginAdapter pluginAdapter) { public void setPluginAdapter(PluginAdapter pluginAdapter) {
this.pluginAdapter = pluginAdapter; this.pluginAdapter = pluginAdapter;
} }
......
...@@ -92,13 +92,32 @@ ...@@ -92,13 +92,32 @@
"1.1": 10 "1.1": 10
} }
} }
],
"": [
{
"consumerServiceName": "",
"providerServiceName": "discovery-springcloud-example-c",
"weightMap": {
"1.0": 80,
"1.1": 20
}
}
] ]
},
"regionWeightEntity": {
"weightMap": {
"dev": 85,
"qa": 15
}
} }
} }
}, },
"customizationEntity": { "customizationEntity": {
"customizationMap": { "customizationMap": {
"discovery-springcloud-example-b": { "discovery-springcloud-example-a": {
"database": "qa"
},
"discovery-springcloud-example-c": {
"database": "prod" "database": "prod"
} }
} }
......
...@@ -73,10 +73,13 @@ ...@@ -73,10 +73,13 @@
<!-- 2. 局部配置,即指定consumer-service-name,专门为该消费端配置权重。全局配置,即不指定consumer-service-name,为所有消费端配置相同情形的权重。当局部配置和全局配置同时存在的时候,以局部配置优先 --> <!-- 2. 局部配置,即指定consumer-service-name,专门为该消费端配置权重。全局配置,即不指定consumer-service-name,为所有消费端配置相同情形的权重。当局部配置和全局配置同时存在的时候,以局部配置优先 -->
<!-- 3. 尽量为线上所有版本都赋予权重值 --> <!-- 3. 尽量为线上所有版本都赋予权重值 -->
<weight> <weight>
<!-- 权重流量配置有如下三种方式,粒度由细到粗,优先级分别是由高到底,即先从第一种方式取权重流量值,取不到则到第二种方式取值,再取不到则到第二种方式取值,再取不到则忽略。使用者按照实际情况,选择一种即可 -->
<!-- 表示消费端服务b访问提供端服务c的时候,提供端服务c的1.0版本提供90%的权重流量,1.1版本提供10%的权重流量 --> <!-- 表示消费端服务b访问提供端服务c的时候,提供端服务c的1.0版本提供90%的权重流量,1.1版本提供10%的权重流量 -->
<service consumer-service-name="discovery-springcloud-example-b" provider-service-name="discovery-springcloud-example-c" provider-weight-value="1.0=90;1.1=10"/> <service consumer-service-name="discovery-springcloud-example-b" provider-service-name="discovery-springcloud-example-c" provider-weight-value="1.0=90;1.1=10"/>
<!-- 表示所有消费端服务访问提供端服务c的时候,提供端服务c的1.0版本提供80%的权重流量,1.1版本提供20%的权重流量 --> <!-- 表示所有消费端服务访问提供端服务c的时候,提供端服务c的1.0版本提供80%的权重流量,1.1版本提供20%的权重流量 -->
<service provider-service-name="discovery-springcloud-example-c" provider-weight-value="1.0=80;1.1=20"/> <service provider-service-name="discovery-springcloud-example-c" provider-weight-value="1.0=80;1.1=20"/>
<!-- 表示外界调用进来后,区域(region)为dev的服务提供85%的权重流量,区域(region)为qa的服务提供15%的权重流量 -->
<!-- <region provider-weight-value="dev=85;qa=15"/> -->
</weight> </weight>
</discovery> </discovery>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment