一、Dubbo简介
Apache Dubbo (incubating) |ˈdʌbəʊ| is a high-performance, java based RPC framework open-sourced by Alibaba. As in many RPC systems, dubbo is based around the idea of defining a service, specifying the methods that can be called remotely with their parameters and return types. On the server side, the server implements this interface and runs a dubbo server to handle client calls. On the client side, the client has a stub that provides the same methods as the server.
二、服务发现
Dubbo默认是Zookeeper注册服务中心。
- Dubbo通过ZookeeperRegistry类来注册和订阅服务,通过zookeeper事件监听服务变更,一旦服务变更,消费端收到通知,然后主动去zookeeper拉取该服务的提供者子目录,这些提供者子目录记录了注册该服务的URL信息。
- RegistryDirectory类封装服务提供者,映射成RegistryDirectory.methodInvokerMap的map类型的属性。
- 客户端端调用服务的方法时,会从RegistryDirectory.methodInvokerMap中取对应的方法的服务提供者URL信息进行RPC调用。
java.lang.Thread.State: RUNNABLE
at com.alibaba.dubbo.registry.zookeeper.ZookeeperRegistry.doSubscribe(ZookeeperRegistry.java:175)
at com.alibaba.dubbo.registry.support.FailbackRegistry.subscribe(FailbackRegistry.java:212)
at com.alibaba.dubbo.registry.integration.RegistryDirectory.subscribe(RegistryDirectory.java:138)
at com.alibaba.dubbo.registry.integration.RegistryProtocol.doRefer(RegistryProtocol.java:277)
at com.alibaba.dubbo.registry.integration.RegistryProtocol.refer(RegistryProtocol.java:260)
at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper.refer(ProtocolFilterWrapper.java:60)
at com.alibaba.qos.protocol.QosProtocolWrapper.refer(QosProtocolWrapper.java:45)
at com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper.refer(ProtocolListenerWrapper.java:67)
at com.alibaba.dubbo.rpc.Protocol$Adaptive.refer(Protocol$Adaptive.java:-1)
at com.alibaba.dubbo.config.ReferenceConfig.createProxy(ReferenceConfig.java:422)
at com.alibaba.dubbo.config.ReferenceConfig.init(ReferenceConfig.java:317)
at com.alibaba.dubbo.config.ReferenceConfig.get(ReferenceConfig.java:147)
- locked <0xaeb> (a com.alibaba.dubbo.config.spring.ReferenceBean)
at com.alibaba.dubbo.config.spring.ReferenceBean.getObject(ReferenceBean.java:130)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:168)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:103)
- locked <0xb51> (a java.util.concurrent.ConcurrentHashMap)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1517)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:251)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:461)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:435)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:559)
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:169)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:305)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1202)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:762)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
- 21行:spring中用到了dubbo的服务,spring会调用AbstractBeanFactory.getBean()去获取这个bean
- 19行:dubbo服务在客户端都是以<dubbo:reference标签配置的,每一个配置都是一个ReferenceBean,ReferenceBean实现了FactoryBean,所以会最终调用FactoryBeanRegistrySupport.getObjectFromFactoryBean()
-
- 12-13行:如果这个dubbo服务类还没有被实例化,会先调用ReferenceConfig.init方法进行实例化,init方法中先合并application,module,consumer,reference中的配置,然后会调用ReferenceConfig.createProxy()生成一个dubbo服务代理类
-
- 11行:运用了扩展点,refprotocol.refer(interfaceClass, url)最终会调用RegistryProtocol.refer()组装了一个Invoker对象,最后通过proxyFactory.getProxy(invoker)生成一个代理(dubbo默认使用了javassist)
-
- 6行:registryFactory.getRegistry(url),通过url中的协议创建相应的注册中心,我们这里是ZookeeperRegistry,ZookeeperRegistry是AbstractRegistry的子类,在AbstractRegistry的构造方法中,首先会加载本地的注册中心的对应dubbo服务,然后会定时把最新的dubbo服务对应关系刷新到本地
-
- 5行:zookeeper注册中心,每个服务下都有这四个配置[configurators, consumers, providers, routers], registry.register()方法会先把Consumer注册到注册中心sonsumers目录下,directory.subscribe()会订阅和监听configurators,providers,routers目录
- 2行:遍历了configurators,providers,routers目录,监听和获取子目录,providers目录下就是可用的dubbo服务providers。新的providers的加入和下架都会通过这里的监听,回调Consumers。