接觸過dubbo的同窗,見到下面的配置都很是熟悉了,含義很少說。java
本章主要目的,對DUBBO配置原理進行剖析。spring
<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:*>標籤,對應的數據載體類。sql
1. 認識標籤對應的數據載體
api
首先,找到dubbo-config\dubbo-config-spring\src\main\resources\META-INF\spring.handlers文件。找到負責具體解析dubbo標籤的handler。併發
http\://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler
查看DubboNamespaceHandler 代碼app
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層次結構異步
如今,應該很容易找出聲明服務的配置入口是哪個配置類:ServiceBean。其餘的類,能夠暫時靠邊站。其餘的配置信息(如ApplicationConfig,RegistryConfig..)主要涉及配置元數據,會決定dubbo運行時行爲,但對梳理剖析DUBBO流程不過重要。async
2.認識ServiceBean
ServiceBean是聲明暴露Service的一個重要組件,須要重點關注。
2.1結構樹
仍是要感謝spring提供的優秀擴展特性,ServiceBean實現了不少spring的擴展接口。如今,把重點放在AbstractConfig繼承樹這個層次上。
AbstractConfig提供基礎支持方法,好比appendAttributes,check*系列方法等。
AbstractMethodConfig,封裝了一些方法級別的相關屬性
AbstractInterfaceConfig:封裝了接口契約須要的屬性
AbstractServiceConfig: 服務相關屬性(重在使用運維級別)
ServiceConfig:主要包含一些運行時數據
AbstractMethodConfig 屬性片斷
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屬性片斷
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 屬性片斷
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屬性片斷
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 有幾個很服務聲明有關的屬性
private final List<Exporter<?>> exporters = new ArrayList<Exporter<?>>(); private transient volatile boolean exported; private transient volatile boolean unexported;
這是剖析服務聲明的入口。