Dubbo|基础知识之dubbo自定义标签解析
上一篇博文了解到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是服务注册核心类,类中包含服务发现和注册的方法。
类的结构图:
该类后续会单独分析。
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);
}
// …
}
类的结构图:
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。