dubbo源码,Dubbo——服务调用、服务暴露、服务引用过程
dubbo源码,Dubbo——服务调用、服务暴露、服务引用过程详细介绍
本文目录一览:
- 1、
- 2、
Dubbo——服务调用、服务暴露、服务引用过程
---
**Dubbo动态代理与集群模块详解**
**一、Invoker与Handler动态代理**
在Dubbo中,InvokerInvocationHandler与JDK动态代理是实现动态代理的关键技术。当服务提供者将服务接口的实现类注册到注册中心后,消费者通过JDK动态代理技术创建服务的代理对象。当调用该代理对象的方法时,实际会调用InvokerInvocationHandler的invoke方法,进而通过JDK动态代理生成具体的Invoker实例。
**二、RegistryDirector与Invokers路由**
RegistryDirector是注册中心的调度器,它负责返回InvokersRouter,该路由器分为Script脚本路由和Condition条件路由等。通过MockInvokersSelector的route方法(如getNormalInvokers),可以获取到能正常执行的invokers列表。
**三、集群模块与容错策略**
Dubbo的集群模块是服务提供者和服务消费者的中间层,为服务消费者屏蔽了服务提供者的情况。集群模块通过cluster来指定集群容错方式,即应对出错情况采取的策略。例如,FailoverClusterInvoker在调用失败时会进行重试,直到成功为止;而FailsafeCluster则在出现异常时,不会进行任何处理,保证服务调用的安全性。此外,还有FailbackCluster、ForkingCluster和BroadcastCluster等多种集群策略。
**四、Invoker的获取与负载均衡**
AbstractClusterInvoker是Invoker的抽象类,它通过select方法选择具体的Invoker。AbstractLoadbalance则负责根据负载均衡策略(如RoundRobinLoadBalance)从invokers列表中选择具体的Invoker。这些操作主要都是读操作,而写操作则是在回调方法notify时进行的,即在注册中心有变化时,会更新methodInvokerMap和urlInvokerMap的值。
**五、服务提供者与消费者的预热与下线处理**
在服务提供者启动时,会将当前进程启动时间注册到ZK。服务消费者在发现该节点后,会计算服务启动时间,并在默认预热时间内对节点权重进行调整。如果某个节点宕机或Hang住,其权重会迅速自动调节降低。当服务提供者优雅下线时,需要在对应的controller中加入逻辑,并判断down是否为true以执行下线操作。
**六、本地暴露与远程暴露**
在Dubbo中,一个服务可能既是提供者又是消费者,因此存在本地暴露和远程暴露的场景。本地暴露用于服务提供者自己调用自己的服务,以避免通过网络访问造成的舍近求远的问题。而远程暴露则是服务提供者将服务注册到注册中心,供消费者远程调用。
**七、SPI机制与拓展性**
SPI(ServiceProviderInterface)是一种服务发现机制,Dubbo通过SPI机制加载所有的组件。虽然Java原生支持SPI机制,但Dubbo对其进行了增强,使其能够更好地满足需求。基于SPI,我们可以很容易地对Dubbo进行拓展,为程序提供更多的功能。
总结:Dubbo通过其精细的集群模块、灵活的容错策略、智能的负载均衡以及强大的拓展性,为微服务架构提供了强大的支持。无论是服务提供者还是消费者,都可以通过简单的配置和代码调用实现高效、可靠的服务调用。
面试官:你给我说一下什么是时间轮吧?
在Dubbo框架中,面试官可能会深入探讨“时间轮”这一关键概念的角色及其工作机制。让我们一同细致地解析这一在分布式服务调用中起到重要作用的技术细节。
时间轮,作为Dubbo集群容错机制的关键策略之一,在FailbackClusterInvoker中发挥着定时重试的职能。这一策略尤其重要,因为在服务调用失败时,它能自动地在每个RETRY_FAILED_PERIOD(默认设置为5秒)后进行重试,直至请求成功或达到重试次数的上限。
具体而言,FailbackClusterInvoker通过ScheduledExecutorService的scheduleWithFixedDelay方法实现这一功能。当请求失败时,它会把请求加入到一个定时重试的队列中。这一过程在官方的Dubbo文档中有详细说明。简单来说,就是不断尝试重新发起请求,直到请求成功或者重试次数达到上限。
时间轮的基本构造是一个数组,它的每个元素代表一个特定的时间点。任务会按照预定的时间顺序被插入到对应的位置。以一个包含8个元素的轮为例,每一圈代表1秒,这样的设计可以扩展以表示更长的时间段。
Dubbo中,FailbackClusterInvoker利用了HashedWheelTimer单例来构建一个守护线程系统。这个系统的构建涉及多个参数,如线程工厂、每个时间周期的时长(tickDuration)以及轮子的大小(ticksPerWheel)。特别地,轮子的大小通常是2的幂次方,以提高效率。
在时间轮的状态管理中,初始化、启动和关闭是三个关键阶段。初始化阶段中,线程会等待计数器计到0,然后启动Worker线程。而startTime的初始化过程则涉及到主线程与Worker线程之间的交互。Worker线程的do-while循环中,通过waitForNextTick方法计算并等待到下一个预定的时间点,确保任务能够按照时间顺序执行。
处理任务时,Dubbo展示了其巧妙的计算方式,既考虑了剩余时间又避免了精度问题。同时,它还对操作系统的中断周期调整有所应对,比如在Windows系统下可能是10ms或15ms的间隔。
值得一提的是,Netty的选择对于HashedWheelTimer的性能影响也是一个讨论的热点。它证明了选择合适的工具和技术栈对于提高Dubbo服务调用的可靠性和效率至关重要。
如果你对这一主题有更深入的兴趣和见解,我们鼓励你参与讨论。共同深化对Dubbo时间轮的理解,为我们的社区贡献你的知识和优化建议。