欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Dubbo|基础知识之dubbo自定义标签解析

程序员文章站 2022-04-30 11:41:57
...

上一篇博文了解到dubbo框架有15个自定义标签,那么每个标签代表什么含义,标签有什么作用,标签内部都有哪些元素等问题还都未知,所以这篇博文就来学习15个自定义标签的含义吧。
所以通过这篇博文可以获取以下几点知识:

  • dubbo框架15个标签的概念及作用
  • dubbo框架15个标签对应的实体类结构
  • 通过15个标签窥探dubbo框架的整体流程

备注:此处dubbo版本为2.7.1,不同版本标签个数不同。2.5版本只有13个标签。

1. dubbo框架15个标签的概念及作用

根据官网文档介绍,依据标签内配置项(元素)的作用可以把元素分为三类:

  • 服务发现:表示该元素用于服务的注册与发现,目的是让消费方找到提供方。
  • 服务治理:表示该元素用于治理服务间的关系,或为开发测试提供便利条件。
  • 性能优化:表示该元素用于调优性能,不同的选项对性能会产生影响。

具体的可以参考官网的介绍,下面在介绍标签的同时,也会顺带介绍标签的各元素。

1.1 标签:application

概念:应用信息配置;用于配置当前应用信息,不管该应用是提供者还是消费者。
标签对应的配置类ApplicationConfig.class

public class ApplicationConfig extends AbstractConfig {
    private static final long serialVersionUID = 5508512956753757169L;
    //用于指定应用名,这里需要保证应用名唯一,这个应用名在后续的console admin中可以在列表中显示,方便管理
private String name; 
    private String version;  // 应用版本号
    private String owner;  // 应用负责人(常用电子邮件前缀表示)
    private String organization;  // 应用的组织名称,便于注册中心区分服务来源
    private String architecture; // 应用服务分层对应的架构
    private String environment; // 应用程序环境,如dev/test/run
    private String compiler; // 应用的Java代码编译器,默认javassist
    private String logger;  // 应用程序日志输出方式,默认为slf4j
    private List<RegistryConfig> registries;  // 应用的注册信息
private String registryIds;
    private MonitorConfig monitor;   // 应用监管对象
    private Boolean isDefault;   // 是否默认,有什么用呢?
private String dumpDirectory;
private Boolean qosEnable;
private Integer qosPort;
private Boolean qosAcceptForeignIp;
private Map<String, String> parameters;
    private String shutwait;

    public ApplicationConfig() {
    }

    public ApplicationConfig(String name) {
        this.setName(name);
    }

    // 省略set get方法
}
1.2 标签:module

概念:模块信息配置类,用于配置当前模块信息,可选。
标签对应的配置类为ModuleConfig.class

public class ModuleConfig extends AbstractConfig {
    private static final long serialVersionUID = 5508512956753757169L;
    private String name; // 模块的名称, 用于注册中心计算模块间依赖关系
    private String version; // 模块版本
    private String owner;  // 模块的负责人 (常用电子邮件前缀表示)
    private String organization; // 模块的组织名称, 用于注册中心区分服务来源
    private List<RegistryConfig> registries; // 模块的注册信息
    private MonitorConfig monitor;  // 模块的监管对象
    private Boolean isDefault;  // 是否默认模块

    public ModuleConfig() {
    }

    public ModuleConfig(String name) {
        this.setName(name);
    }

    // 省略set get方法
}

备注:该标签内元素都属于“服务治理”。

1.3 标签:registry

概念:注册中心配置,用于配置连接注册中心相关信息。同时如果有多个不同的注册中心,可以声明多个 < dubbo:registry> 标签,并在 < dubbo:service> 或 < dubbo:reference> 的 registry 属性指定使用的注册中心。
标签对应的配置类为RegistryConfig.class

public class RegistryConfig extends AbstractConfig {
    private static final long serialVersionUID = 5508512956753757169L;
    public static final String NO_AVAILABLE = "N/A";
    private String address; // 注册中心服务器地址,不同集群则配置多个
    private String username; // 登录注册中心用户名
    private String password; // 登录注册中心密码
    private Integer port;  // 注册中心服务器默认端口
    private String protocol;  // 注册中心服务器地址协议
    private String transporter; // 注册中心协议传输类型
    private String server;  // 协议服务类型
    private String client;  // 协议客户端类型
    private String cluster; // 注册集群类型
    private String group;  // 服务注册分组
    private String version; // 版本号
    private Integer timeout;  // 注册中心请求超时时间
    private Integer session;  // 注册中心会话超时时间
    // 使用文件缓存注册中心地址列表及服务提供者列表,应用重启时将基于此文件恢复
    private String file;  
    private Integer wait;  // 停止时等待通知完成时间(毫秒)
    private Boolean check;  // 注册中心不存在时,是否报错
    private Boolean dynamic; //注册到此注册中心的服务是动态的(true)或静态的(false)
    private Boolean register; // 服务是否注册到本注册中心,是为true,否为false
    // 是否向此注册中心订阅服务,如果设为false,将只注册,不订阅
    private Boolean subscribe; 
    private Map<String, String> parameters;
    private Boolean isDefault;  // 是否默认
    private Boolean simplified; // 注册到注册中心的URL是否采用精简模式的
    private String extraKeys;  // 额外的参数键

    public RegistryConfig() {
    }
    public RegistryConfig(String address) {
        this.setAddress(address);
    }
    // 省略get set方法

}
1.4 标签:provider

概念:服务提供者缺省值配置,同时该标签为 < dubbo:service> 和 < dubbo:protocol> 标签的缺省值设置,可选。
该标签对应的配置类为ProviderConfig.class

public class ProviderConfig extends AbstractServiceConfig {
    private static final long serialVersionUID = 6913423882496634749L;
    private String host;  // 服务主机
    private Integer port;  // 服务端口号
    private String contextpath;  // 协议上下文路径,被path取代了
    private String threadpool;  // 线程池类型
    private Integer threads;   // 线程池大小
    private Integer iothreads;  // io线程池大小
    private Integer queues;  // 线程池队列大小
    private Integer accepts;  // 服务接收连接大小
    private String codec;    // 服务编码协议
    private String charset;  // 协议字符集
    private Integer payload;  // 最大有效载荷
    private Integer buffer;  // 缓冲区大小
    private String transporter;  // 协议传输类型
    private String exchanger;  // 协议交换类型
    private String dispatcher; // 协议分发类型
    private String networker;  // 协议网络类型
    private String server; // 协议服务器类型
    private String client;  // 协议客户端类型
    private String telnet;  // 协议使用telnet命令
    private String prompt;  // 协议telnet提示符
    private String status;  // 协议检查状态
    private Integer wait;  // 提供者关闭等待时间
    private Boolean isDefault;  // 是否默认

    public ProviderConfig() {
    }
	// 省略set get方法
}
1.5 标签:consumer

概念:服务消费者缺省值配置,同时该标签为 dubbo:reference 标签的缺省值设置,可选。
该标签对应的配置类为ConsumerConfig.class

public class ConsumerConfig extends AbstractReferenceConfig {
    private static final long serialVersionUID = 2827274711143680600L;
    private Boolean isDefault;  // 是否默认
    private String client; // 传输层框架:netty,mina…
    private String threadpool;  // 消费线程池:cached fixed limited eager
    private Integer corethreads; // 线程池核心线程数
    private Integer threads;  // 线程池大小
    private Integer queues;  // 线程池队列大小
    private Integer shareconnections; // 默认共享连接,默认值为1
    public ConsumerConfig() {
    }
    // 省略set get方法
}
1.6 标签:protocol

概念:服务提供者协议配置,用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受。如果需要支持多协议,可以声明多个 < dubbo:protocol> 标签,并在 < dubbo:service> 中通过 protocol 属性指定使用的协议。
该标签对应的配置类为ProtocolConfig.class

public class ProtocolConfig extends AbstractConfig {
    private static final long serialVersionUID = 6913423882496634749L;
    private String name;  // 协议名称
    private String host;  // 服务主机
    private Integer port;  // 服务端口
    private String contextpath;  // 协议上下文路径
    private String threadpool;  // 线程池类型
    private Integer corethreads; // 线程池核心线程数
    private Integer threads;  // 线程池大小
    private Integer iothreads;  // io线程池大小
    private Integer queues;  // 线程池队列大小
    private Integer accepts;  // 接收连接大小
    private String codec;  // 编码协议
    private String serialization;  // 协议序列化
    private String charset;  // 协议字符集
    private Integer payload;  // 最大负载
    private Integer buffer;  // 缓冲大小
    private Integer heartbeat;  // heartbeat间隔(ms)
    private String accesslog;  // The protocol use accesslog
    private String transporter;  // 协议传输器类型
    private String exchanger;  // 协议交换器类型
    private String dispatcher;  // 协议调度类型
    private String networker;  // 协议“networker”类型
    private String server;  // 协议服务类型
    private String client;  // 协议客户端类型
    private String telnet;  // 协议使用telnet命令
    private String prompt;  //协议telnet提示符
    private String status;  // 协议检查状态
    private Boolean register;  // 协议是否可以被注册
    private Boolean keepAlive; // 是否存活
    private String optimizer;  // 序列化优化器
    private String extension;  // 协议扩展
    private Map<String, String> parameters;  //
    private Boolean isDefault;  // 是否默认

    public ProtocolConfig() {
    }

    public ProtocolConfig(String name) {
        this.setName(name);
    }

    public ProtocolConfig(String name, int port) {
        this.setName(name);
        this.setPort(port);
    }
    // 省略set get方法
}
1.7 标签:service

概念:服务提供者暴露服务配置,用于暴露一个服务,定义服务的元信息,一个服务可以用多个协议暴露,一个服务也可以注册到多个注册中心。
该标签对应的配置类为ServiceBean.class

public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener<ContextRefreshedEvent>, BeanNameAware, ApplicationEventPublisherAware {
    private static final long serialVersionUID = 213195494150089726L;
    private final transient Service service; // 服务基本信息,用定义为注解
    private transient ApplicationContext applicationContext; // 应用信息
    private transient String beanName;  // 服务bean的名称
    private transient boolean supportedApplicationListener; // 是否支持事件监听
    private ApplicationEventPublisher applicationEventPublisher; // 事件发布

    public ServiceBean() {
        this.service = null;
    }

    public ServiceBean(Service service) {
        super(service);
        this.service = service;
    }
    // 省略方法…
}

ServiceBean是服务注册核心类,类中包含服务发现和注册的方法。
类的结构图:
Dubbo|基础知识之dubbo自定义标签解析
该类后续会单独分析。

1.8 标签:reference

概念:服务消费者引用服务配置,用于创建一个远程服务代理,一个引用可以指向多个注册中心。
该标签对应的配置类为ReferenceBean.class

public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean, ApplicationContextAware, InitializingBean, DisposableBean {
    private static final long serialVersionUID = 213195494150089726L;
    private transient ApplicationContext applicationContext;

    public ReferenceBean() {
    }

    public ReferenceBean(Reference reference) {
        super(reference);
    }
    // …
}

类的结构图:
Dubbo|基础知识之dubbo自定义标签解析

1.9 标签:metadata-report

概念:元数据配置类。
该标签对应的配置类为MetadataReportConfig.class

public class MetadataReportConfig extends AbstractConfig {
    private static final long serialVersionUID = 55233L;
    private static final String PREFIX_TAG = StringUtils.camelToSplitName(MetadataReportConfig.class.getSimpleName().substring(0, MetadataReportConfig.class.getSimpleName().length() - 6), "-");
    private String address;
    private String username;
    private String password;
    private Integer timeout;
    private String group;
    private Map<String, String> parameters;
    private Integer retryTimes;
    private Integer retryPeriod;
    private Boolean cycleReport;
    private Boolean syncReport;

    public MetadataReportConfig() {
    }

    public MetadataReportConfig(String address) {
        this.setAddress(address);
    }
    // …
}
1.10 标签:config-center

概念:配置中心类。
该标签对应的配置类为ConfigCenterBean.class

public class ConfigCenterBean extends ConfigCenterConfig implements InitializingBean, ApplicationContextAware, DisposableBean, EnvironmentAware {
    private transient ApplicationContext applicationContext;
    private Boolean includeSpringEnv = false;
    private ApplicationConfig application;

    public ConfigCenterBean() {
    }
    // …
}

继承自ConfigCenterConfig.class

public class ConfigCenterConfig extends AbstractConfig {
    private AtomicBoolean inited = new AtomicBoolean(false); // 是否已被初始化
    private String protocol; // 配置中心协议
    private String address;  // 配置中心地址
    private String cluster;  // 配置中心集群
    private String namespace = "dubbo";  // 配置中心命名空间
    private String group = "dubbo";  // 配置中心的组别, 同一配置中心用于配置项的独立空间
    private String username;  // 获取配置中心权限的用户名
    private String password;  // 获取配置中心权限的密码
    private Long timeout = 3000L;  // 配置中心请求超时时间
    private Boolean highestPriority = true;  // 配置中心的配置是否最高优先级
    private Boolean check = true;  // 连接到配置中心失败时应用的策略
    private String appName;  // 配置中心的组名
    private String configFile = "dubbo.properties";  // 配置中心配置文件
    private String appConfigFile;   // 用于在启动时获取配置的秘钥
    private Map<String, String> parameters;

    public ConfigCenterConfig() {}
}
1.11 标签:annotaion

概念:注解配置,用于扫描package包下面的注解(包括service和reference)。

1.12 标签:monitor

概念:监控中心配置,用于配置连接监控中心相关信息,可选。
该标签对应的配置类为MonitorConfig.class

public class MonitorConfig extends AbstractConfig {
    private static final long serialVersionUID = -1184681514659198203L;
    private String protocol;  //监控中心协议
    private String address;  // 监控中心地址,缺省值“N/A”
    private String username; // 监控中心登录用户名
    private String password; // 监控中心登录密码
    private String group;  // 监控中心分组
    private String version; // 监控中心版本号
    private Map<String, String> parameters;
    private Boolean isDefault; // 是否默认

    public MonitorConfig() {
    }

    public MonitorConfig(String address) {
        this.address = address;
    }

    // 省略set get方法
}
1.13 标签:method

概念:方法级配置。同时该标签为 < dubbo:service> 或 < dubbo:reference> 的子标签,用于控制到方法级。
该标签对应的配置类为MethodConfig.class

public class MethodConfig extends AbstractMethodConfig {
    private static final long serialVersionUID = 884908855422675941L;
    private String name;   // 方法名
    private Integer stat;  
    // 远程服务调用重试次数,不包括第一次调用,不需要重试请设为0
    private Boolean retry; 
    private Boolean reliable;
    // 每方法最大使用线程数限制,此属性只在method标签作为service子标签时才有效
    private Integer executes; 
    // 方法是否遗弃, 此属性只在method标签作为service子标签时才有效
    private Boolean deprecated; 
    //设置true 该接口上的所有方法使用同一个provider.如果需要更复杂的规则,请使用用路由
    private Boolean sticky;  
    private Boolean isReturn; // 方法是否有返回值
    private Object oninvoke;  // 方法执行前拦截
    private String oninvokeMethod;
    private Object onreturn; // 方法执行返回后拦截
    private String onreturnMethod;
    private Object onthrow;  // 方法执行有异常拦截
    private String onthrowMethod;
    private List<ArgumentConfig> arguments;
    private String service;
    private String serviceId;
    // 省略set get方法
}
1.14 标签:argument

概念:方法参数配置。该标签为 dubbo:method 的子标签,用于方法参数的特征描述;比如:

<dubbo:method name="findXxx" timeout="3000" retries="2">
    <dubbo:argument index="0" callback="true" />
</dubbo:method>

备注:可以通过index(参数索引)确定参数位置,也可以通过type(参数类型)确定参数位置。callback值表示参数是否为callback接口,如果为callback,服务提供方将生成反向代理,可以从服务提供方反向调用消费方,通常用于事件推送。

1.15 标签:parameter

概念:选项参数配置。该标签为< dubbo:protocol>或< dubbo:service>或< dubbo:provider>或< dubbo:reference>或< dubbo:consumer>的子标签,用于配置自定义参数,该配置项将作为扩展点设置自定义参数使用。
该标签对应的配置类为Map.class
使用实例:

<dubbo:protocol name="napoli">
    <dubbo:parameter key="http://10.20.160.198/wiki/display/dubbo/napoli.queue.name" value="xxx" />
</dubbo:protocol>

2 从标签看Dubbo框架

让我们先来想一个问题:dubbo为什么要自定义一套标签
没有标签,dubbo框架是否可以使用?毫无疑问,API、配置文件和注解完全可以替代标签来使用dubbo,所以可以认为,dubbo自定义的标签可以使我们通过xml形式使用dubbo,不是必须存在,而是一种补充。
那么,为什么不利用Spring中的< bean>标签而必须自定义一套标签呢

假如使用< bean>标签来实例化dubbo框架中的对象,则需要在xml中明确类的路径名,这将会进一步耦合xml配置文件和dubbo框架;假如下个版本某个类的路径名被修改,那么项目中的xml配置文件也要作相应的修改,这将异常繁杂;所以,自定义的标签可以使得项目与Dubboo框架解耦

Dubbo框架充分利用面向对象的思想,把核心流程中的各个环节抽象成对象。比如应用抽象为ApplicationConfig,服务抽象为ServiceConfig,协议抽象为Protocol,甚至把服务对象内的方法都抽象为MethodConfig。