美文网首页
1.1-服务提供者启动流程

1.1-服务提供者启动流程

作者: xhrg | 来源:发表于2018-12-26 11:08 被阅读0次

一:入口

  • 在dubbo-2.5.3.jar中的META-INF下有一个文件是spring.handlers里面配置了一个类是com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler,这个便是dubbo的入口。(原理可以看spring-schema扩展)
public class DubboNamespaceHandler extends NamespaceHandlerSupport {
    static {
        Version.checkDuplicate(DubboNamespaceHandler.class);
    }
     // 这个类DubboNamespaceHandler 会把xml中配置的一些标签注册为bean解析器,比如说遇到provider这个字符串就会用下面对应的Parser去解析,所以下面的字符串application,module,registry都会对应到不同的Parse实例。
    public void init() {
        registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
        registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
        registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
        registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
        registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
        registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
        registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
        //比如说配置了<dubbo:service ref="personService" interface="com.wang.dubbo.api.PersonService" protocol="dubbo" />
        //这个时候就会用DubboBeanDefinitionParser去解析这个标记,然后组装ServiceBean对象。
        registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
        registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
        registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true));
    }

}

如果遇到<dubbo:service ref="personService" interface="com.wang.dubbo.api.PersonService" protocol="dubbo" />,解析代码是在DubboBeanDefinitionParser的parse方法中,dubbo-2.5.3.jar的231行。

beanDefinition.getPropertyValues().addPropertyValue(property, reference);

这里的beanDefinition指的是RootBeanDefinition实例,内部的BeanClass是com.alibaba.dubbo.config.spring.ServiceBean,
这里的property, reference分别是interface和com.wang.dubbo.api.PersonService。到此已经可以看到,解析成功,组装了ServiceBean。

二:ServiceBean的启动

  • ServiceBean实现了众多的spring扩展点(InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener, BeanNameAware,扩展点主要是会在spring容器加载的时候,调用一些钩子方法)
  • ServiceBean中有2个比较核心的方法,是afterPropertiesSet,onApplicationEvent
  • ServiceBean还继承了很多类,这些类是链式的继承关系,每个类都包含了很多属性:如下:
    • ServiceBean
    • ServiceConfig
    • AbstractServiceConfig
    • AbstractInterfaceConfig
    • AbstractMethodConfig
    • AbstractConfig
    • Serializable
2.1 afterPropertiesSet

第一步,设置属性,包括:

  • setProvider(providerConfig);
  • setApplication(applicationConfig);
  • setModule(moduleConfig);
  • super.setRegistries(registryConfigs);
  • setMonitor(monitorConfig);
  • super.setProtocols(protocolConfigs);
  • setPath(beanName);
2.2 onApplicationEvent

该方法会调用export(); 实现真实的服务启动发布

三:export方法

export先做属性等的设置,然后做检查,最后调用doExportUrls。

  • 3.1 loadRegistries:先拿到所有的注册地址:List<URL> registryURLs = loadRegistries(true);,然后循环注册地址去注册
  • 3.2 doExportUrlsFor1Protocol: InetAddress.getLocalHost().getHostAddress();(获取本机Ip地址)
  • 3.3 获取本机ip地址,获取端口地址,获取方法名称,获取版本号,获取同步异步等信息组装成Map,然后根据Map生成url:比如说以下URL

dubbo://192.168.122.23:20880/com.wang.dubbo.api.PersonService?anyhost=true&application=Dubbo_HelloWorld&dubbo=2.5.3&interface=com.wang.dubbo.api.PersonService&methods=say&pid=59448&side=provider&timestamp=1545891510122

  • 3.4 exportLocal:暴露本地服务(比如说jvm实例内部调用其实不需要走网络,所以这里会先放到本地)
    • 3.4.1 生成本地URL :injvm://127.0.0.1/com.wang.dubbo.api.PersonService?xxxxx(省略)
    • 3.4.2 根据实例(PersonServiceImpl,)接口,URL ,生成Invoker(详情见ProxyFactory:getInvoker),再往里面是JavassistProxyFactory|getInvoker获取Invoker。
    • 生成 Invoker后会包装成Exporter ,把Exporter 放在List<Exporter<?>> exporters中,该List是ServiceConfig的属性。
  • 3.5 暴露本地服务完了后会根据registryURLs暴露到相关地址上,比如说暴露到zk上。
    • 3.5.1 暴露远程服务也是一样的 Invoker<?> invoker = proxyFactory.getInvoker,Exporter<?> exporter = protocol.export(invoker);先根据proxyFactory获取代理对象,然后根据protocol暴露并且转化为Exporter。

三:protocol.export(invoker) 方法

  • RegistryProtocol|export -> doLocalExport(originInvoker); 该调用会启动netty服务,监听请求。
  • 该方法会对应到一个实现是RegistryProtocol中的export,在这个方法中会读取zk信息,把URL写入ZK。到此过程中一个dubbo服务提供者发布完成。

四:doLocalExport(RegistryProtocol|exporth)

该方法调用到底层会调用到DubboProtocol的export,该方法内部会openServer。 openServer 会启动netty监听端口。
大致的调用链如下(笔记的写法和eclipse的显示上下相反)

  • DubboProtocol:openServer
  • DubboProtocol:createServer
  • Exchangers:bind
  • HeaderExchanger:bind
  • Transporters:bind
  • NettyTransporter:bind
  • new NettyServer(url, listener); 到此接受请求就会进入NettyHandler(该类继承SimpleChannelHandler)

当client调用的时候,拿到请求数据,会解析成Request,然后处理后返回,核心代码在HeaderExchangeHandler中

Response response = handleRequest(exchangeChannel, request);

AbstractProtocol的exporterMap会缓存Exporter,其中key是接口名+端口,比如说com.wang.dubbo.api.PersonService:20880,
然后从Exporter中拿到invoker,invoker.invoke(Invocation inv);返回结果invoke到实际类调用中间会经过非常多的Filter。

最后

dubbo服务者发布过程中的很多信息,都会记录在该ServiceBean的属性中。

相关文章

  • 1.1-服务提供者启动流程

    一:入口 在dubbo-2.5.3.jar中的META-INF下有一个文件是spring.handlers里面配置...

  • Spring-Cloud服务发现Eureka的服务调用详细入门教

    案例中有三个角色:服务注册中心、服务提供者、服务消费者,流程是首先启动注册中心,服务提供者生产服务并注册到服务中心...

  • 服务注册与发现

    SpringCloud服务注册与发现主要交互流程如下: 【服务提供者】启动时向【注册中心】注册,【注册中心】维护注...

  • Laravel 服务提供者是如何注册的

    1. 服务提供者配置: 2. 服务提供者主要方法: 3. 注册服务提供者流程 3.1 注册流程的过程大概 3.1...

  • 断路器 (Hystrix Feign)

    启动【服务中心】集群,Eureka Server 启动【服务提供者】集群,Eureka Client 启动【服务消...

  • Dubbo架构

    架构 调用关系说明 服务容器负责启动,加载,运行服务提供者。 服务提供者在启动时,向注册中心注册自己提供的服务。 ...

  • Boot 服务 直接使用OpenFeign来使用

    服务提供者:只是简单的boot,没有使用Cloud 服务调用者: 启动服务调用者 和 启动服务提供者 请求:lo...

  • Dubbo入门

    架构 服务容器负责启动,加载,运行服务提供者。 服务提供者在启动时,向注册中心注册自己提供的服务。 服务消费者在启...

  • Dubbo学习文档

    入门 - 架构 节点角色说明 调用关系说明 服务容器负责启动,加载,运行服务提供者。 服务提供者在启动时,向注册中...

  • 《分布式_Dubbo》_Dubbo整体概述

    Dubbo模块划分很明确,简单做个概述 简单架构图 流程说明: Provider(提供者)绑定指定端口并启动服务 ...

网友评论

      本文标题:1.1-服务提供者启动流程

      本文链接:https://www.haomeiwen.com/subject/edthlqtx.html