[dubbo 源码之 ]1. 服务提供方如何发布服务

服务发布 启动流程 1.ServiceConfig#export

服务提供方在启动部署时,dubbo会调用ServiceConfig#export来激活服务发布流程,如下所示:

Java API:
```java
// 1. 创建ServiceConfig实例
ServiceConfig serviceConfig = new ServiceConfig<>();
// 2. 设置应用程序配置
serviceConfig.setApplication(new ApplicationConfig("deep-in-dubbo-first-provider"));
// 3. 设置注册中心
RegistryConfig registryConfig = new RegistryConfig("zookeeper://127.0.0.1:2181/");
serviceConfig.setRegistry(registryConfig);
// 4. 设置接口和实现类
// 5. 设置服务分组和版本
// dubbo中,服务接口+服务分组+服务版本 唯一的确定一个服务,同一个接口可以有不同版本,方便维护升级
serviceConfig.setInterface(IGreetingService.class);
serviceConfig.setRef(new GreetingServiceImpl());
serviceConfig.setVersion("1.0.0");
serviceConfig.setGroup("dubbo-sxzhongf-group");
RpcContext.getContext().setAttachment("age","18");

// 7. 导出服务,启动Netty监听链接请求,并将服务注册到注册中心 serviceConfig.export(); // 8. 挂起线程,避免服务停止 System.out.println("api provider service is started..."); System.in.read();

```

XML

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- provider's application name, used for tracing dependency relationship --> <dubbo:application/> <!-- use multicast registry center to export service --> <dubbo:registry address="zookeeper://127.0.0.1:2181/"/> <!-- use dubbo protocol to export service on port 20880 --> <dubbo:protocol port="20880"/> <!-- service implementation, as same as regular local bean --> <bean/> <!-- declare the service interface to be exported --> <dubbo:service interface="com.sxzhongf.deep.in.dubbo.api.service.IGreetingService" ref="demoService" version="1.0.0" group="dubbo-sxzhongf-group"> <dubbo:method async="false" timeout="0" retries="3"></dubbo:method> <dubbo:method async="false" timeout="10000" retries="3"></dubbo:method> </dubbo:service> </beans>

查看export源码可知,总共有三种服务导出选项:
java public synchronized void export() { //1. 是否导出 if (!shouldExport()) { return; } ... //2.延迟导出 if (shouldDelay()) { DELAY_EXPORT_EXECUTOR.schedule(this::doExport, getDelay(), TimeUnit.MILLISECONDS); } else { //3.立刻导出 doExport(); } }

2.ServiceConfig#doExport

此方法主要是根据设置的属性进行合法性检查,主要包含是否已被导出,doExportUrls();

3.doExportUrls 4.ConfigValidationUtils#loadRegistries

此方法用来加载所有的服务注册中心对象,在dubbo中,一个service可以被注册到多个注册中心。

通过doExportUrlsFor1Protocol(protocolConfig, registryURLs);

5.doExportUrlsFor1Protocol

在此方法中会将所有的参数封装成org.apache.dubbo.common.URL对象,然后执行具体的服务导出。

具体过程分为:

1.解析MethodConfig配置(单独的方法调用参数设置)

2.泛型调用类型设置

3.拼接URL参数

4.导出具体服务

导出又分为四种范围(scope):

SCOPE_NONE = "none",如果设定为none,表示该服务不导出。

SCOPE_LOCAL = "local" ,如果设定为local,表示该服务导出到本地(injvm--伪协议,实现类为:org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol)

SCOPE_REMOTE = "remote",如果设定为remote,表示该服务导出到远程。

如果有注册中心,发布到注册中心

如果没有注册中心,则表示服务是直连方式

从dubbo-2.7.0开始,新增加了WritableMetadataService 来存储dubbo 服务的元数据,元数据可以存储在远端配置中心和本地,默认是存储在本地,通过设置:METADATA_KEY = "metadata"

DEFAULT_METADATA_STORAGE_TYPE = "local"

REMOTE_METADATA_STORAGE_TYPE = "remote"
java /** * @since 2.7.0 * ServiceData Store */ WritableMetadataService metadataService = WritableMetadataService.getExtension(url.getParameter(METADATA_KEY, DEFAULT_METADATA_STORAGE_TYPE)); if (metadataService != null) { metadataService.publishServiceDefinition(url); }

不设置,导出到本地和远端

最终执行导出的代码如下

// 扩展适配类 private static final Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension(); /** * A {@link ProxyFactory} implementation that will generate a exported service proxy,the JavassistProxyFactory is its * default implementation */ // 扩展适配类 private static final ProxyFactory PROXY_FACTORY = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension(); ... Invoker<?> invoker = PROXY_FACTORY.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(EXPORT_KEY, url.toFullString())); DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this); Exporter<?> exporter = protocol.export(wrapperInvoker); exporters.add(exporter);

由于protocol和PROXY_FACTORY都是扩展适配类,跟踪代码我们可以发现:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpgpjz.html