dubbo框架原理

148 阅读3分钟

一、Dubbo提供的功能

  1. 基于接口的远程调用
  2. 容错和负载均衡
  3. 自动服务注册和发现

二、Dubbo的总体架构

Dubbo源码的包结构

  • dubbo-admin:dubbo自带的控制台管理,用于服务治理和监控
  • dubbo-cluster:集群模块,将多个服务提供方伪装为一个提供方,包括负载均衡、容错、路由等。
  • dubbo-common:公共逻辑模块
  • dubbo-config:配置模块,是Dubbo对外API,用户通过config使用Dubbo,隐藏Dubbo所有细节
  • dubbo-containter:容器模块,以简单的Main加载Sping的启动。
  • dubbo-filter:主要针对dubbo-rpc里面的Filter进行缓存和校验
  • dubbo-monitor:主要统计服务的调用次数和调用时间
  • dubbo-register:注册中心模块,基于注册中心下发地址的集群方式,以及对各种注册中心的抽象
  • dubbo-remoting:远程通信模块,包括Netty等多种通信方式
  • dubbo-rpc:远程调用模块,抽奖各种协议,已经动态代理。

Dubbo的分层

  • Service层:这一层与业务实现相结合,根据具体业务实现服务提供者和消费者
  • Config层:配置信息层,由spring解析服务提供者和消费者的配置信息,封装到ServiceConfig和ReferenceConfig中
  • Proxy层:服务代理层,这一层主要结合SPI机制,动态选取不同的配置类
  • Register层:服务注册层,主要负责注册与发现Dubbo服务,以及对Dubbo服务的监听
  • Cluster层:服务集群层,负责服务的路由、负载以及失败重试策略
  • Protocol层:协议层,在这层进行相关协议的转换与过滤
  • Exchange层:封装请求响应模式
  • Transport层:网络传输层,抽象Netty等,在这一层进行真正的数据传输
  • Serialize层:序列化层,根据不同的协议对数据进行序列化

三、Dubbo Bean的加载

1、spring自定义标签的使用

在spring中完成一个自定义标签需要以下几步

  • 设计配置属性和JavaBean
  • 编写XSD文件
  • 编写BeanDefinitionPaster标签解析类
  • 在META-INF下定义spring.handlers和spring.schemas供spring读取

下面来实现spring标签

public class FeiConfig {
    private String id;
    private String path;
}
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns="http://fei.ma/schema/fei"
            targetNamespace="http://fei.ma/schema/fei">
	<xsd:element name="config">
		<xsd:complexType>
			<xsd:attribute name="id" type="xsd:string"/>
			<xsd:attribute name="path" type="xsd:string"/>
		</xsd:complexType>
	</xsd:element>	
</xsd:schema>

<!-- XML配置文件 -->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:fei="http://fei.ma/schema/fei"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
           http://fei.ma/schema/fei
           http://fei.ma/schema/fei/fei.xsd">
    <fei:config id="mafei1" path="com.fei.plug.FeiConfig"></fei:config>
    <fei:config id="mafei2" path="com.fei.plug.FeiConfig"></fei:config>
</beans>
public class FeiBeanDefinitionParser implements BeanDefinitionParser {

    public FeiBeanDefinitionParser() {
    }
    @Override
    public BeanDefinition parse(Element element, ParserContext parserContext) {
        //解析xml内容
        String id = element.getAttribute("id");
        String path = element.getAttribute("path");
         //注册beanDefine到spring容器
        RootBeanDefinition beanDefinition = new RootBeanDefinition();
        beanDefinition.setBeanClass(FeiConfig.class);
        beanDefinition.setLazyInit(false);
        beanDefinition.getPropertyValues().add("path", path);
        parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);
        return beanDefinition;
    }
}
public class FeiNamespaceHandler extends NamespaceHandlerSupport {
    private Logger logger = LoggerFactory.getLogger(FeiNamespaceHandler.class);
    @Override
    public void init() {
        logger.info("----{}------", "FeiNamespaceHandler");
        //注意此处的config是xml中的标签
        registerBeanDefinitionParser("config", new FeiBeanDefinitionParser());
    }
}
spring.handler
http://fei.ma/schema/fei=com.fei.plug.FeiNamespaceHandler
spring.schemas
http://fei.ma/schema/fei/fei.xsd=META-INF/fei.xsd

这样spring标签就已经完成了下面我们来看看效果吧

自定义标签配置已经完成了。

2、再看看dubbo是如果实现的

从这段源码中可以看到dubbo的自定义标签有10个,所有的标签都统一使用DubboBeanDefinitionParser进行解析,基于一对一属性映射,将XML标签解析为Bean对象。这里分析了dubbo框架中的对象加载配置与加载的原理,并做了一个demo帮助大家理解。后面继续分析dubbo消费者与生产者的原理与实现。