一、服务注册
当确定好了最终的服务配置后,Dubbo就会根据这些配置信息生成对应的服务URL,比如:
dubbo://192.168.65.221:20880/org.apache.dubbo.springboot.demo.DemoService?
application=dubbo-springboot-demo-provider&timeout=3000
这个URL就表示了一个Dubbo服务,服务消费者只要能获得到这个服务URL,就知道了关于这个
Dubbo服务的全部信息,包括服务名、支持的协议、ip、port、各种配置。
确定了服务URL之后,服务注册要做的事情就是把这个服务URL存到注册中心(比如Zookeeper)中去,说的再简单一点,就是把这个字符串存到Zookeeper中去,这个步骤其实是非常简单的,实现这个功能的源码在RegistryProtocol中的export()方法中,最终服务URL存在了Zookeeper的/dubbo/接口名/providers目录下。
但是服务注册并不仅仅就这么简单,既然上面的这个URL表示一个服务,并且还包括了服务的一些配置信息,那这些配置信息如果改变了呢?比如利用Dubbo管理台中的动态配置功能(注意,并不是配置中心)来修改服务配置,动态配置可以应用运行过程中动态的修改服务的配置,并实时生效。
如果利用动态配置功能修改了服务的参数,那此时就要重新生成服务URL并重新注册到注册中心,这样服务消费者就能及时的获取到服务配置信息。而对于服务提供者而言,在服务注册过程中,还需要能监听到动态配置的变化,一旦发生了变化,就根据最新的配置重新生成服务URL,并重新注册到中心。
一、接口级注册
一、接口级注册原理
首先,我们可以通过配置dubbo.application.register-mode来控制:
1. instance:表示只进行应用级注册
2. interface:表示只进行接口级注册
3. all:表示应用级注册和接口级注册都进行,默认
在Dubbo3.0之前,Dubbo是接口级注册,服务注册就是把接口名以及服务配置信息注册到注册中心中,我们把dubbo.application.register-mode设置为interface,看到注册中心(zookeeper)存储的数据格式大概为:

总结来说就是:
接口名1:dubbo://192.168.65.221:20880/接口名1?application=应用名
接口名2:dubbo://192.168.65.221:20880/接口名2?application=应用名
接口名3:dubbo://192.168.65.221:20880/接口名3?application=应用名
key是接口名,value就是服务URL,上面的内容就表示现在有一个应用,该应用下有3个接口,应用实例部署在192.168.65.221,此时,如果给该应用增加一个实例,实例ip为192.168.65.222,那么新的实例也需要进行服务注册,会向注册中心新增3条数据:
接口名1:dubbo://192.168.65.221:20880/接口名1?application=应用名
接口名2:dubbo://192.168.65.221:20880/接口名2?application=应用名
接口名3:dubbo://192.168.65.221:20880/接口名3?application=应用名
接口名1:dubbo://192.168.65.222:20880/接口名1?application=应用名
接口名2:dubbo://192.168.65.222:20880/接口名2?application=应用名
接口名3:dubbo://192.168.65.222:20880/接口名3?application=应用名
可以发现,如果一个应用中有3个Dubbo服务,那么每增加一个实例,就会向注册中心增加3条记录,那如果一个应用中有10个Dubbo服务,那么每增加一个实例,就会向注册中心增加10条记录,注册中心的压力会随着应用实例的增加而剧烈增加。
反过来,如果一个应用有3个Dubbo服务,5个实例,那么注册中心就有15条记录,此时增加一个
Dubbo服务,那么注册中心就会新增5条记录,注册中心的压力也会剧烈增加。
所以这就是接口级注册的弊端。
二、源码流程分析
dubbo服务启动的时候首先会来到doExportUrls方法:
private void doExportUrls() {
ModuleServiceRepository repository = getScopeModel().getServiceRepository();
ServiceDescriptor serviceDescriptor = repository.registerService(getInterfaceClass());
providerModel = new ProviderModel(getUniqueServiceName(),
ref,
serviceDescriptor,
this,
getScopeModel(),
serviceMetadata);
repository.registerProvider(providerModel);
List<URL> registryURLs = ConfigValidationUtils.loadRegistries(this, true);
for (ProtocolConfig protocolConfig : protocols) {
String pathKey = URL.buildKey(getContextPath(protocolConfig)
.map(p -> p + "/" + path)
.orElse(path), group, version);
// In case user specified path, register service one more time to map it to path.
repository.registerService(pathKey, interfaceClass);
doExportUrlsFor1Protocol(protocolConfig, registryURLs);
}
}
ConfigValidationUtils.loadRegistries方法根据服务配置获取注册信息registryURLs,内容如下
registry://localhost:2181/org.apache.dubbo.registry.RegistryService?REGISTRY_CLUSTER=registryConfig&appl

最低0.47元/天 解锁文章
706

被折叠的 条评论
为什么被折叠?



