开篇
继Dubbo Admin 数据获取原理文章之后,我们要具体看下Dubbo Admin各类如何动态修改配置,这篇文章主要分析动态调整权重的过程。
权重修改后consumer的响应流程分析请参考Dubbo 动态规则配置分析和Dubbo 动态规则作用域说明。
文章是基于dubbo-2.6.0的版本进行分析。
provider侧权重调整
- 提供者provider侧权重调整在提供者这栏通过倍权或者半权进行调整。
consumer侧权重调整
- 消费者consumer侧权重调整在消费者这栏通过编辑进行调整。
权重调整记录
- provider和consumer侧的权重调整记录在权重调节栏展示。
- 权重调节栏的新增功能个人感觉没有什么用,因为如果针对consumer侧的权重调整必须填写的是consumer的ip地址而不是provider的ip地址,所以这个功能持保留意见。
Provider侧权重调整流程分析
public class ProviderServiceImpl extends AbstractService implements ProviderService {
public void setWeight(Long id, float factor) {
if (id == null) {
throw new IllegalStateException("no provider id");
}
Provider oldProvider = findProvider(id);
if (oldProvider == null) {
throw new IllegalStateException("Provider was changed!");
}
Map<String, String> map = StringUtils.parseQueryString(oldProvider.getParameters());
String weight = map.get(Constants.WEIGHT_KEY);
// 针对provider是动态注册的场景
if (oldProvider.isDynamic()) {
// 根据service名和provider的地址获取overrides信息。
List<Override> overrides = overrideService.findByServiceAndAddress(oldProvider.getService(), oldProvider.getAddress());
// 针对第一次添加override的场景处理
if (overrides == null || overrides.size() == 0) {
int value = getWeight(weight, factor);
if (value != Constants.DEFAULT_WEIGHT) {
Override override = new Override();
override.setAddress(oldProvider.getAddress());
override.setService(oldProvider.getService());
override.setEnabled(true);
override.setParams(Constants.WEIGHT_KEY + "=" + String.valueOf(value));
overrideService.saveOverride(override);
}
} else {
// 针对非第一次添加override的场景处理
for (Override override : overrides) {
Map<String, String> params = StringUtils.parseQueryString(override.getParams());
String overrideWeight = params.get(Constants.WEIGHT_KEY);
if (overrideWeight == null || overrideWeight.length() == 0) {
overrideWeight = weight;
}
int value = getWeight(overrideWeight, factor);
if (value == getWeight(weight, 1)) {
params.remove(Constants.WEIGHT_KEY);
} else {
params.put(Constants.WEIGHT_KEY, String.valueOf(value));
}
if (params.size() > 0) {
override.setParams(StringUtils.toQueryString(params));
overrideService.updateOverride(override);
} else {
overrideService.deleteOverride(override.getId());
}
}
}
} else {
// 针对provider是非动态注册的场景
int value = getWeight(weight, factor);
if (value == Constants.DEFAULT_WEIGHT) {
map.remove(Constants.WEIGHT_KEY);
} else {
map.put(Constants.WEIGHT_KEY, String.valueOf(value));
}
oldProvider.setParameters(StringUtils.toQueryString(map));
updateProvider(oldProvider);
}
}
}
- provider侧的权重调整根据provider的service名称和address的地址查找是否有对应的overrides规则。
- 如果之前没有任何overrides规则,那么就执行saveOverride的save操作。
- 如果之前有overrides规则,那么就执行updateOverride的update操作。
Consumer侧权重调整流程分析
public class Consumers extends Restful {
public boolean update(Consumer newConsumer, Map<String, Object> context) {
Long id = newConsumer.getId();
String parameters = newConsumer.getParameters();
Consumer consumer = consumerService.findConsumer(id);
if (consumer == null) {
context.put("message", getMessage("NoSuchOperationData", id));
return false;
}
String service = consumer.getService();
if (!super.currentUser.hasServicePrivilege(service)) {
context.put("message", getMessage("HaveNoServicePrivilege", service));
return false;
}
Map<String, String> oldMap = StringUtils.parseQueryString(consumer.getParameters());
Map<String, String> newMap = StringUtils.parseQueryString(parameters);
for (Map.Entry<String, String> entry : oldMap.entrySet()) {
if (entry.getValue().equals(newMap.get(entry.getKey()))) {
newMap.remove(entry.getKey());
}
}
String address = consumer.getAddress();
List<Override> overrides = overrideService.findByServiceAndAddress(consumer.getService(), consumer.getAddress());
OverrideUtils.setConsumerOverrides(consumer, overrides);
Override override = consumer.getOverride();
if (override != null) {
// consumer非第一次添加权重修改
if (newMap.size() > 0) {
override.setParams(StringUtils.toQueryString(newMap));
override.setEnabled(true);
override.setOperator(operator);
override.setOperatorAddress(operatorAddress);
overrideService.updateOverride(override);
} else {
overrideService.deleteOverride(override.getId());
}
} else {
// consumer第一次添加权重修改
override = new Override();
override.setService(service);
override.setAddress(address);
override.setParams(StringUtils.toQueryString(newMap));
override.setEnabled(true);
override.setOperator(operator);
override.setOperatorAddress(operatorAddress);
overrideService.saveOverride(override);
}
return true;
}
}
- consumer侧的权重调整根据consumer的service名称和address的地址查找是否有对应的overrides规则。
- 如果之前没有任何overrides规则,那么就执行saveOverride的save操作。
- 如果之前有overrides规则,那么就执行updateOverride的update操作。
权重调整执行过程
public class OverrideServiceImpl extends AbstractService implements OverrideService {
public void saveOverride(Override override) {
URL url = getUrlFromOverride(override);
registryService.register(url);
}
public void updateOverride(Override override) {
Long id = override.getId();
if (id == null) {
throw new IllegalStateException("no override id");
}
URL oldOverride = findOverrideUrl(id);
if (oldOverride == null) {
throw new IllegalStateException("Route was changed!");
}
URL newOverride = getUrlFromOverride(override);
registryService.unregister(oldOverride);
registryService.register(newOverride);
}
public void deleteOverride(Long id) {
URL oldOverride = findOverrideUrl(id);
if (oldOverride == null) {
throw new IllegalStateException("Route was changed!");
}
registryService.unregister(oldOverride);
}
public void enableOverride(Long id) {
if (id == null) {
throw new IllegalStateException("no override id");
}
URL oldOverride = findOverrideUrl(id);
if (oldOverride == null) {
throw new IllegalStateException("Override was changed!");
}
if (oldOverride.getParameter("enabled", true)) {
return;
}
URL newOverride = oldOverride.addParameter("enabled", true);
registryService.unregister(oldOverride);
registryService.register(newOverride);
}
public void disableOverride(Long id) {
if (id == null) {
throw new IllegalStateException("no override id");
}
URL oldProvider = findOverrideUrl(id);
if (oldProvider == null) {
throw new IllegalStateException("Override was changed!");
}
if (!oldProvider.getParameter("enabled", true)) {
return;
}
URL newProvider = oldProvider.addParameter("enabled", false);
registryService.unregister(oldProvider);
registryService.register(newProvider);
}
}
- OverrideServiceImpl执行的是overrides规则的真正执行操作。
- saveOverride负责在注册中心注册新的overrides的url地址。
- updateOverride负责在注册中心执行删除旧的overrides的url地址并添加新的overrides的url地址。
权重调整的URL
provider侧的权重调整URL的例子
override://192.168.1.5:20880/com.alibaba.dubbo.demo.DemoService?category=configurators&dynamic=false&enabled=true&weight=400
consumer侧的权重调整URL例子
override://192.168.1.5/com.alibaba.dubbo.demo.DemoService?category=configurators&dynamic=false&enabled=true&weight=70
- provider和consumer权重调整的URL地址中区别在于provider的地址相比于consumer的地址多了一个port字段。