1.dubbo定义的服务,通过spring.handerls对应到DubboNamespaceHandler类
//DubboNamespaceHandler的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));
2.关注service定义的ServiceBean,实现了多个spring的接口,其中包括ApplicationListener和InitializingBean的接口
//举例说明默认的dubbo服务的注册, 先从ServiceBean的export()开始
public void afterPropertiesSet(){
export();
}
//当有service注册到applicationContext完成时
public void onApplicationEvent(ApplicationEvent event) {
if (ContextRefreshedEvent.class.getName().equals(event.getClass().getName())) {
if (isDelay() && ! isExported() && ! isUnexported()) {
if (logger.isInfoEnabled()) {
logger.info("The service ready on spring started. service: " + getInterface());
}
export();
}
}
}
3.ProtocolFilterWrapper包装DubboProtocol,调用DubboProtocol.export()方法进行发布,其中做了两件事情。
a)用netty建立一个server
b)起了一个线程定时跑HeaderExchangeServer.startHeatbeatTimer()对所有的客户端连接的chanel进行轮询发送心跳,并计算最后一次发送接受的时间差。
c)参见HeartBeatTask的run方法
public void run() { try { long now = System.currentTimeMillis(); for ( Channel channel : channelProvider.getChannels() ) { if (channel.isClosed()) { continue; } try { Long lastRead = ( Long ) channel.getAttribute( HeaderExchangeHandler.KEY_READ_TIMESTAMP ); Long lastWrite = ( Long ) channel.getAttribute( HeaderExchangeHandler.KEY_WRITE_TIMESTAMP ); if ( ( lastRead != null && now - lastRead > heartbeat ) || ( lastWrite != null && now - lastWrite > heartbeat ) ) { Request req = new Request(); req.setVersion( "2.0.0" ); req.setTwoWay( true ); req.setEvent( Request.HEARTBEAT_EVENT ); channel.send( req ); if ( logger.isDebugEnabled() ) { logger.debug( "Send heartbeat to remote channel " + channel.getRemoteAddress() + ", cause: The channel has no data-transmission exceeds a heartbeat period: " + heartbeat + "ms" ); } } if ( lastRead != null && now - lastRead > heartbeatTimeout ) { logger.warn( "Close channel " + channel + ", because heartbeat read idle time out: " + heartbeatTimeout + "ms" ); if (channel instanceof Client) { try { ((Client)channel).reconnect(); }catch (Exception e) { //do nothing } } else { channel.close(); } } } catch ( Throwable t ) { logger.warn( "Exception when heartbeat to remote channel " + channel.getRemoteAddress(), t ); } } } catch ( Throwable t ) { logger.warn( "Unhandled exception when heartbeat, cause: " + t.getMessage(), t ); } }
4.其中ProtocolListenerWrapper,提供了相关的监听事件给使用者去用,源码中并没有具体的实现
public Exporter export(Invoker invoker) throws RpcException {
if (Constants.REGISTRY_PROTOCOL.equals(invoker.getUrl().getProtocol())) {
return protocol.export(invoker);
}
return new ListenerExporterWrapper(protocol.export(invoker),
Collections.unmodifiableList(ExtensionLoader.getExtensionLoader(ExporterListener.class)
.getActivateExtension(invoker.getUrl(), Constants.EXPORTER_LISTENER_KEY)));
}
public Invoker refer(Class type, URL url) throws RpcException {
if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
return protocol.refer(type, url);
}
return new ListenerInvokerWrapper(protocol.refer(type, url),
Collections.unmodifiableList(
ExtensionLoader.getExtensionLoader(InvokerListener.class)
.getActivateExtension(url, Constants.INVOKER_LISTENER_KEY)));
}
5.zookeeper注册的过程主要是ZookeeperRegistry类
a)客户端建立连接到注册中心
b)sendEvent线程专门发送和接收消息(举例:比如心跳到zookeeper中心)
c)eventThread专门处理各种连接事件,并抛给上层的真正的handler线程,由handler线程sendTo相应的队列,这个时候由dubbo实现监听事件并处理