Dubbo点滴(3)之服务配置ServiceConfig

简介:

接触过dubbo的同学,见到下面的配置都非常熟悉了,含义不多说。

本章主要目的,对DUBBO配置原理进行剖析。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
< beans  xmlns = "http://www.springframework.org/schema/beans"
     xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
     xmlns:dubbo = "http://code.alibabatech.com/schema/dubbo"
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
     http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
     ">
      
     <!-- 当前应用信息配置 -->
     < dubbo:application  name = "demo-provider"  />
     
     <!-- 连接注册中心配置 -->
     < dubbo:registry  address = "N/A"  />
      
     <!-- 暴露服务协议配置 -->
     < dubbo:protocol  name = "dubbo"  port = "20813"  />
     
     <!-- 暴露服务配置 -->
     < dubbo:service  interface = "com.alibaba.dubbo.config.spring.api.DemoService" 
     ref = "demoService"  />
      
     < bean  id = "demoService" 
     class = "com.alibaba.dubbo.config.spring.impl.DemoServiceImpl"  />
  
</ beans >

spring加载xml或annotation,第一步需要将这些配置元数据载入spring容器中,首先确认下这些<dubbo:*>标签,对应的数据载体类。

1. 认识标签对应的数据载体

首先,找到dubbo-config\dubbo-config-spring\src\main\resources\META-INF\spring.handlers文件。找到负责具体解析dubbo标签的handler。

1
http\://code.alibabatech.com/ schema /dubbo=com.alibaba.dubbo.config.spring. schema .DubboNamespaceHandler

查看DubboNamespaceHandler 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public  class  DubboNamespaceHandler  extends  NamespaceHandlerSupport {
 
    static  {
       Version.checkDuplicate(DubboNamespaceHandler. class );
    }
 
    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 ));
         registerBeanDefinitionParser( "service" new  DubboBeanDefinitionParser(ServiceBean. class true ));
         registerBeanDefinitionParser( "reference" new  DubboBeanDefinitionParser(ReferenceBean. class false ));
         registerBeanDefinitionParser( "annotation" new  DubboBeanDefinitionParser(AnnotationBean. class true ));
     }
 
}

不再进行分析具体代码了。这部分内容和spring的范畴。

1.1对应表格

标签
数据配置类
含义
<dubbo:application name="demo-provider" />
ApplicationConfig
应用级别
<dubbo:registry address="N/A" />
RegistryConfig
注册中心
<dubbo:protocol name="dubbo" 
port="20813" />
ProtocolConfig 协议
<dubbo:service interface=".." 
ref="demoService" />
ServiceBean
服务
module
ModuleConfig
模块
monitor MonitorConfig
监控
consumer ConsumerConfig 消费者
provider
ProviderConfig 提供者
reference
ReferenceBean 服务引用

1.2 Config层次结构

wKiom1hWaZjBJQW_AABLM5B6bOY383.png



现在,应该很容易找出声明服务的配置入口是哪一个配置类:ServiceBean。其他的类,可以暂时靠边站。其他的配置信息(如ApplicationConfig,RegistryConfig..)主要涉及配置元数据,会决定dubbo运行时行为,但对梳理剖析DUBBO流程不太重要。

2.认识ServiceBean

ServiceBean是声明暴露Service的一个重要组件,需要重点关注。

2.1结构树

wKioL1hWbIzQUhrNAABPVdsPmdk818.png

还是要感谢spring提供的优秀扩展特性,ServiceBean实现了很多spring的扩展接口。现在,把重点放在AbstractConfig继承树这个层次上。

AbstractConfig提供基础支持方法,比如appendAttributes,check*系列方法等。

AbstractMethodConfig,封装了一些方法级别的相关属性

AbstractInterfaceConfig:封装了接口契约需要的属性

AbstractServiceConfig:    服务相关属性(重在使用运维级别)

ServiceConfig:主要包含一些运行时数据


AbstractMethodConfig 属性片段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public  abstract  class  AbstractMethodConfig  extends  AbstractConfig {
// 远程调用超时时间(毫秒)
protected  Integer             timeout;
 
// 重试次数
protected  Integer             retries;
 
// 最大并发调用
protected  Integer             actives;
 
// 负载均衡
protected  String              loadbalance;
 
// 是否异步
protected  Boolean             async;
 
// 异步发送是否等待发送成功
protected  Boolean             sent;
 
// 服务接口的失败mock实现类名
protected  String              mock;
 
// 合并器
protected  String              merger;
 
// 服务接口的失败mock实现类名
protected  String              cache;
 
// 服务接口的失败mock实现类名
protected  String              validation;
..
}

AbstractInterfaceConfig.java属性片段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
public  abstract  class  AbstractInterfaceConfig  extends  AbstractMethodConfig {
 
     private  static  final  long       serialVersionUID = -1559314110797223229L;
 
     // 服务接口的本地实现类名
     protected  String               local;
 
     // 服务接口的本地实现类名
     protected  String               stub;
 
     // 服务监控
     protected  MonitorConfig        monitor;
     
     // 代理类型
     protected  String               proxy;
     
     // 集群方式
     protected  String               cluster;
 
     // 过滤器
     protected  String               filter;
     
     // 监听器
     protected  String               listener;
 
     // 负责人
     protected  String               owner;
 
     // 连接数限制,0表示共享连接,否则为该服务独享连接数
     protected  Integer              connections;
     
     // 连接数限制
     protected  String               layer;
     
     // 应用信息
     protected  ApplicationConfig    application;
     
     // 模块信息
     protected  ModuleConfig         module;
 
     // 注册中心
     protected  List<RegistryConfig> registries;
     
     // callback实例个数限制
     private  Integer                callbacks;
     
     // 连接事件
     protected  String              onconnect;
     
     // 断开事件
     protected  String              ondisconnect;
 
     // 服务暴露或引用的scope,如果为local,则表示只在当前JVM内查找.
    private  String scope;
    ...
    }

AbstractServiceConfig 属性片段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public  abstract  class  AbstractServiceConfig  extends  AbstractInterfaceConfig {
 
     private  static  final  long       serialVersionUID = 1L;
 
     // 服务版本
     protected  String               version;
 
     // 服务分组
     protected  String               group;
 
     // 服务是否已经deprecated
     protected  Boolean              deprecated;
 
     // 延迟暴露
     protected  Integer              delay;
 
     // 是否暴露
     protected  Boolean              export;
 
     // 权重
     protected  Integer              weight;
 
     // 应用文档
     protected  String               document;
 
     // 在注册中心上注册成动态的还是静态的服务
     protected  Boolean              dynamic;
 
     // 是否使用令牌
     protected  String               token;
 
     // 访问日志
     protected  String               accesslog;
 
     // 允许执行请求数
     private  Integer                executes;
 
     protected  List<ProtocolConfig> protocols;
 
     // 是否注册
     private  Boolean                register;
     ...
     }

ServiceConfig.java属性片段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public  class  ServiceConfig<T>  extends  AbstractServiceConfig {
 
     private  static  final  long    serialVersionUID = 3033787999037024738L;
 
     private  static  final  Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol. class ).getAdaptiveExtension();
     
     private  static  final  ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory. class ).getAdaptiveExtension();
 
     private  static  final  Map<String, Integer> RANDOM_PORT_MAP =  new  HashMap<String, Integer>();
 
     // 接口类型
     private  String              interfaceName;
 
     private  Class<?>            interfaceClass;
 
     // 接口实现类引用
     private  T                   ref;
 
     // 服务名称
     private  String              path;
 
     // 方法配置
     private  List<MethodConfig>  methods;
 
     private  ProviderConfig provider;
 
     private  final  List<URL> urls =  new  ArrayList<URL>();
     
     private  final  List<Exporter<?>> exporters =  new  ArrayList<Exporter<?>>();
 
     private  transient  volatile  boolean  exported;
 
    private  transient  volatile  boolean  unexported;
     
     private  transient  volatile  boolean  generic;
     ...
     }

注意ServiceConfig 有几个很服务声明有关的属性

1
2
3
4
5
     private  final  List<Exporter<?>> exporters =  new  ArrayList<Exporter<?>>();
 
     private  transient  volatile  boolean  exported;
 
     private  transient  volatile  boolean  unexported;

这是剖析服务声明的入口。


本文转自 randy_shandong 51CTO博客,原文链接:http://blog.51cto.com/dba10g/1883784,如需转载请自行联系原作者

相关文章
|
8月前
|
XML Dubbo Java
【Dubbo3高级特性】「框架与服务」服务的异步调用实践以及开发模式
【Dubbo3高级特性】「框架与服务」服务的异步调用实践以及开发模式
174 0
|
8月前
|
Dubbo Java 应用服务中间件
Dubbo服务暴露机制解密:深入探讨服务提供者的奥秘【九】
Dubbo服务暴露机制解密:深入探讨服务提供者的奥秘【九】
110 0
|
8月前
|
SpringCloudAlibaba Dubbo Java
SpringCloud Alibaba集成Dubbo实现远程服务间调用
SpringCloud Alibaba集成Dubbo实现远程服务间调用
|
3月前
|
监控 Dubbo Java
dubbo学习三:springboot整合dubbo+zookeeper,并使用dubbo管理界面监控服务是否注册到zookeeper上。
这篇文章详细介绍了如何将Spring Boot与Dubbo和Zookeeper整合,并通过Dubbo管理界面监控服务注册情况。
224 0
dubbo学习三:springboot整合dubbo+zookeeper,并使用dubbo管理界面监控服务是否注册到zookeeper上。
|
5月前
|
JSON Dubbo Java
【Dubbo协议指南】揭秘高性能服务通信,选择最佳协议的终极攻略!
【8月更文挑战第24天】在分布式服务架构中,Apache Dubbo作为一款高性能的Java RPC框架,支持多种通信协议,包括Dubbo协议、HTTP协议及Hessian协议等。Dubbo协议是默认选择,采用NIO异步通讯,适用于高要求的内部服务通信。HTTP协议通用性强,利于跨语言调用;Hessian协议则在数据传输效率上有优势。选择合适协议需综合考虑性能需求、序列化方式、网络环境及安全性等因素。通过合理配置,可实现服务性能最优化及系统可靠性提升。
79 3
|
5月前
|
缓存 Dubbo Java
Dubbo服务消费者启动与订阅原理
该文章主要介绍了Dubbo服务消费者启动与订阅的原理,包括服务消费者的启动时机、启动过程以及订阅和感知最新提供者信息的方式。
Dubbo服务消费者启动与订阅原理
|
5月前
|
Dubbo 网络协议 Java
深入掌握Dubbo服务提供者发布与注册原理
该文章主要介绍了Dubbo服务提供者发布与注册的原理,包括服务发布的流程、多协议发布、构建Invoker、注册到注册中心等过程。
深入掌握Dubbo服务提供者发布与注册原理
|
5月前
|
负载均衡 Dubbo Java
Dubbo服务Spi机制和原理
该文章主要介绍了Dubbo中的SPI(Service Provider Interface)机制和原理,包括SPI的基本概念、Dubbo中的SPI分类以及SPI机制的实现细节。
Dubbo服务Spi机制和原理
|
7月前
|
Dubbo 前端开发 Java
Dubbo3 服务原生支持 http 访问,兼具高性能与易用性
本文展示了 Dubbo3 triple 协议是如何简化从协议规范与实现上简化开发测试、入口流量接入成本的,同时提供高性能通信、面向接口的易用性编码。
16667 15
|
5月前
|
C# 开发者 Windows
勇敢迈出第一步:手把手教你如何在WPF开源项目中贡献你的第一行代码,从选择项目到提交PR的全过程解析与实战技巧分享
【8月更文挑战第31天】本文指导您如何在Windows Presentation Foundation(WPF)相关的开源项目中贡献代码。无论您是初学者还是有经验的开发者,参与这类项目都能加深对WPF框架的理解并拓展职业履历。文章推荐了一些适合入门的项目如MvvmLight和MahApps.Metro,并详细介绍了从选择项目、设置开发环境到提交代码的全过程。通过具体示例,如添加按钮点击事件处理程序,帮助您迈出第一步。此外,还强调了提交Pull Request时保持专业沟通的重要性。参与开源不仅能提升技能,还能促进社区交流。
57 0