dubbo.application.register-mode
参数
参数含义
interface
只接口级注册(/dubbo)
instance
只应用级注册(/service)
all
接口级注册与应用级注册并存(/dubbo && /service)
dubbo.application.service-discovery.migration
参数
参数含义
FORCE_INTERFACE
只消费接口级地址,如无地址则报错,单订阅2.x地址
APPLICATION_FIRST
智能决策接口级还是应用级地址,双订阅 (先查询接口级 在查询应用级)
FORCE_APPLICATION
只消费应用级地址,如无地址则报错,单订阅3.x地址
源码解析
在上一节中有说到 服务启动流程 中会执行到不同版本的
org.apache.dubbo.config.ServiceConfig#exportOnly
或者
org.apache.dubbo.config.ServiceConfig#export
方法, 在方法内部调用
List registryURLs = ConfigValidationUtils.loadRegistries(this, true);
获取URL, 我们具体看下 该方法调用
//org.apache.dubbo.config.utils.ConfigValidationUtils#loadRegistries
public static List<URL> loadRegistries(AbstractInterfaceConfig interfaceConfig, boolean provider) {
// 此处调用是为了得到 register协议的URL
//eg: registry://127.0.0.1:2181/org.apache.dubbo.registry.RegistryService?application=provider&client=curator&dubbo=2.0.2&pid=8093®istry=zookeeper&release=3.0.4×tamp=1640861452691
List<URL> registryList = new ArrayList<URL>();
ApplicationConfig application = interfaceConfig.getApplication();
List<RegistryConfig> registries = interfaceConfig.getRegistries();
if (CollectionUtils.isNotEmpty(registries)) {
for (RegistryConfig config : registries) {
String address = config.getAddress();
if (StringUtils.isEmpty(address)) {
address = ANYHOST_VALUE;
}
if (!RegistryConfig.NO_AVAILABLE.equalsIgnoreCase(address)) {
Map<String, String> map = new HashMap<String, String>();
AbstractConfig.appendParameters(map, application);
AbstractConfig.appendParameters(map, config);
map.put(PATH_KEY, RegistryService.class.getName());
AbstractInterfaceConfig.appendRuntimeParameters(map);
if (!map.containsKey(PROTOCOL_KEY)) {
map.put(PROTOCOL_KEY, DUBBO_PROTOCOL);
}
List<URL> urls = UrlUtils.parseURLs(address, map);
for (URL url : urls) {
url = URLBuilder.from(url)
.addParameter(REGISTRY_KEY, url.getProtocol())
.setProtocol(extractRegistryType(url))
.setScopeModel(interfaceConfig.getScopeModel())
.build();
if ((provider && url.getParameter(REGISTER_KEY, true))
|| (!provider && url.getParameter(SUBSCRIBE_KEY, true))) {
registryList.add(url);
}
}
}
}
}
//此处会对register-mode做判断
return genCompatibleRegistries(interfaceConfig.getScopeModel(), registryList, provider);
}
//org.apache.dubbo.config.utils.ConfigValidationUtils#genCompatibleRegistries
private static List<URL> genCompatibleRegistries(ScopeModel scopeModel, List<URL> registryList, boolean provider) {
List<URL> result = new ArrayList<>(registryList.size());
registryList.forEach(registryURL -> {
//判断是否为 provider
if (provider) {
String registerMode;
//判断是否为 service-discovery-registry 协议
if (SERVICE_REGISTRY_PROTOCOL.equals(registryURL.getProtocol())) {
//获取定义的register-mode值
registerMode = registryURL.getParameter(REGISTER_MODE_KEY, ConfigurationUtils.getCachedDynamicProperty(scopeModel, DUBBO_REGISTER_MODE_DEFAULT_KEY, DEFAULT_REGISTER_MODE_INSTANCE));
if (!isValidRegisterMode(registerMode)) {
registerMode = DEFAULT_REGISTER_MODE_INSTANCE;
}
result.add(registryURL);
//判断register_mode 是否 为all模式 并且 registryURL不是registry协议
if (DEFAULT_REGISTER_MODE_ALL.equalsIgnoreCase(registerMode)
&& registryNotExists(registryURL, registryList, REGISTRY_PROTOCOL)) {
URL interfaceCompatibleRegistryURL = URLBuilder.from(registryURL)
.setProtocol(REGISTRY_PROTOCOL)
.removeParameter(REGISTRY_TYPE_KEY)
.build();
result.add(interfaceCompatibleRegistryURL);
}
} else {
//进来此处说明 registryURL的协议为 registry
//获取定义的register-mode值
registerMode = registryURL.getParameter(REGISTER_MODE_KEY, ConfigurationUtils.getCachedDynamicProperty(scopeModel, DUBBO_REGISTER_MODE_DEFAULT_KEY, DEFAULT_REGISTER_MODE_ALL));
if (!isValidRegisterMode(registerMode)) {
registerMode = DEFAULT_REGISTER_MODE_INTERFACE;
}
//如果register-mode的值定义的为 instance 或 all
if ((DEFAULT_REGISTER_MODE_INSTANCE.equalsIgnoreCase(registerMode) || DEFAULT_REGISTER_MODE_ALL.equalsIgnoreCase(registerMode))
&& registryNotExists(registryURL, registryList, SERVICE_REGISTRY_PROTOCOL)) {
//封装为service-discovery-registry协议
URL serviceDiscoveryRegistryURL = URLBuilder.from(registryURL)
.setProtocol(SERVICE_REGISTRY_PROTOCOL)
.removeParameter(REGISTRY_TYPE_KEY)
.build();
//将service-discovery-registry协议的URL加入到集合
result.add(serviceDiscoveryRegistryURL);
}
//如果register-mode的值定义的为 interface 或 all
if (DEFAULT_REGISTER_MODE_INTERFACE.equalsIgnoreCase(registerMode) || DEFAULT_REGISTER_MODE_ALL.equalsIgnoreCase(registerMode)) {
//将registry协议的URL加入到集合
result.add(registryURL);
}
}
FrameworkStatusReportService reportService = ScopeModelUtil.getApplicationModel(scopeModel).getBeanFactory().getBean(FrameworkStatusReportService.class);
reportService.reportRegistrationStatus(reportService.createRegistrationReport(registerMode));
} else {
result.add(registryURL);
}
});
return result;
}