2.Dubbo之架构源码公共知识

Dubbo三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

1.核心注解分析

目前Dubbo支持两种注册方式:应用级别以及接口级别的。

初学Dubbo在Web应用中的使用时经常用的注解为:@EnableDubbo@DubboReference@DubboService三个,下面简单分析一下注解是如何发挥作用的。

@EnableDubbo注解主要Import两个 ImportBeanDefinitionRegistrar 类型的子类:DubboComponentScanRegistrar、DubboConfigConfigurationRegistrar。但是DubboConfigConfigurationRegistrar可能是早期的版本,其功能完全可以被DubboComponentScanRegistrar取代。

DubboComponentScanRegistrar内部主要是在Spring IOC中增加类DubboSpringInitContext接口级别的ModuleModel应用级别的ApplicationModel等相关实例。并且注册一些Dubbo框架需要使用到的核心bean,例如DubboDeployApplicationListener、DubboInfraBeanRegisterPostProcessor、DubboConfigApplicationListener等。

@DubboService注解标识的目标类主要是被后置处理器ServiceAnnotationPostProcessor加载到Spring IOC对应的注册表中。

DubboClassPathBeanDefinitionScanner扫描指定路径下dubbo涉及的bean。如果@EnableDubbo没有显式指定路径,则默认为启动类所在的包路径,此时意味着Dubbo需要遍历应用中所有类是否为候选类,所以显示指定路径可以提升应用启动速率。

Dubbo中目标接口的多个实现类必须通过version版本号区别。针对每个候选类在Spring IOC中存在两种形式,一种是beanName + Class属性(候选类真实Class类型),另一种是 beanName:version + Class属性为ServiceBean。最后一种形式也是后置处理器ServiceAnnotationPostProcessor类涉及的核心功能。

@DubboReference注解是被后置处理器ReferenceAnnotationBeanPostProcessor解析的。当前后置处理器比较关注的注解如下所示分别为Reference、DubboReference。

public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBeanPostProcessor{
	public ReferenceAnnotationBeanPostProcessor() {
        super(DubboReference.class, Reference.class, com.alibaba.dubbo.config.annotation.Reference.class);
    }
}

简单概括为:遍历Spring IOC注册表中全部的类,如果类的字段或者方法上存在Reference|DubboReference等相关注解则生成该接口对应的BeanDefinition。但是BeanDefinition中Class属性为ReferenceBean类信息。

ReferenceBean是FactoryBean类型的类,核心就是为了创建候选类的代理类,无论是JDK动态代理还是Cglib动态代理。但是在Dubbo中代理过程是参考Spring AOP 代理流程来完成的。

2.ApplicationListener类型的监听器

Dubbo架构中主要存在三种类型的监听器:DubboConfigApplicationListener、DubboConfigBeanDefinitionConflictApplicationListener、DubboDeployApplicationListener。

  • DubboDeployApplicationListener、DubboConfigBeanDefinitionConflictApplicationListener先后均触发ContextRefreshedEvent事件。
  • DubboConfigApplicationListener监听器处理的事件类型是由ReferenceAnnotationBeanPostProcessor发布的DubboConfigInitEvent的事件。该类型的事件是在刷新IOC容器过程中触发的,也就是ContextRefreshedEvent事件触发之前发生的。

2.1.DubboConfigApplicationListener

作用:加载Dubbo涉及的相关配置。
配置文件Dubbo相关的配置信息并非由SpringBoot框架直接与实体类建立映射关系,而是利用Dubbo内置Environment加载得到jvm配置信息、系统配置信息、应用配置信息等,分别与AbstractConfig的子类进行对比,符合前提下创建对应的实例并初始化实例属性的value。

public class DubboConfigApplicationListener implements ApplicationListener<DubboConfigInitEvent>{

    @Override
    public void onApplicationEvent(DubboConfigInitEvent event) {
        if (nullSafeEquals(applicationContext, event.getSource())) {
            if (initialized.compareAndSet(false, true)) {
                initDubboConfigBeans();
            }
        }
    }

    private void initDubboConfigBeans() {
        // All infrastructure config beans are loaded, initialize dubbo here
        moduleModel.getDeployer().prepare();//DefaultModuleDeployer
    }
}

具体参考

2.2.DubboDeployApplicationListener

作用:触发服务注册功能。

3.服务zk节点信息

如图所示服务在zk创建的节点信息:

在这里插入图片描述

其中消费端节点信息如下:

{
    "name": "dubbo-consumer",
    "id": "ip:20880",
    "address": "ip",
    "port": 20880,
    "sslPort": null,
    "payload": {
        "@class": "org.apache.dubbo.registry.zookeeper.ZookeeperInstance",
        "id": "ip:20880",
        "name": "dubbo-consumer",
        "metadata": {
            "dubbo.endpoints": "[{\"port\":20880,\"protocol\":\"dubbo\"}]",
            "dubbo.metadata-service.url-params": "{\"serialization\":\"compactedjava\",\"connections\":\"1\",\"version\":\"1.0.0\",\"dubbo\":\"2.0.2\",\"release\":\"3.0.7\",\"side\":\"provider\",\"port\":\"20880\",\"protocol\":\"dubbo\"}",
            "dubbo.metadata.revision": "5adab1f6190c5e8e332960354cbd8403",
            "dubbo.metadata.storage-type": "local"
        }
    },
    "registrationTimeUTC": 1712915872096,
    "serviceType": "DYNAMIC",
    "uriSpec": null
}

提供端节点信息如下:

{
    "name": "dubbo-provider",
    "id": "ip:20880",
    "address": "ip",
    "port": 20880,
    "sslPort": null,
    "payload": {
        "@class": "org.apache.dubbo.registry.zookeeper.ZookeeperInstance",
        "id": "ip:20880",
        "name": "dubbo-provider",
        "metadata": {
            "dubbo.endpoints": "[{\"port\":20880,\"protocol\":\"dubbo\"}]",
            "dubbo.metadata-service.url-params": "{\"connections\":\"1\",\"version\":\"1.0.0\",\"dubbo\":\"2.0.2\",\"release\":\"3.0.7\",\"side\":\"provider\",\"port\":\"20880\",\"protocol\":\"dubbo\"}",
            "dubbo.metadata.revision": "f2f3e2c0abb3b7e0e048c29b53eef957",
            "dubbo.metadata.storage-type": "local"
        }
    },
    "registrationTimeUTC": 1712461748518,
    "serviceType": "DYNAMIC",
    "uriSpec": null
}
  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值