为了账号安全,请及时绑定邮箱和手机立即绑定

Dubbo两个核心模块-Registry和Remoting简明教程

标签:
Java

前面我们了解了Dubbo的特性和顶层架构,这一篇让我们大致了解下Dubbo的两个核心模块。

Dubbo是一个精耕服务治理领域的框架,秉承了阿里一贯的大而全风格,和Eureka相比复杂度有不小的提高,这一节我们选了Registry和Remoting两个核心模块,从功能层面做个简单的了解(后面的章节会深入介绍底层原理)

Registry是Dubbo中负责服务注册的模块,也就是我们熟悉的注册中心,目前Dubbo支持五种不同的注册中心,其中登场率最高的就是Zookeeper了。

Zookeeper是Apache Hadoop的子项目,它底层是一个树形的目录结构,同时支持基于发布订阅模型的变更推送,这个特性特别适合应用在注册中心服务上。Zookeeper在各个大厂都有广泛应用,其稳定性和性能已经在业界得到了充分证明。大家如果想进一步了解Zookeeper可以逛逛官方开源文档:http://zookeeper.apache.org

关于Registry的细节部分将在稍后一小节深入讲解,在这之前我们先了解下Dubbo在服务注册功能上的主要特点:

注册中心的运作方式

注册中心只承担服务治理相关的功能(注册、发现、心跳和下线等),它不承担消息的转发(这一点和Eureka一样),因此不用承担访问压力。和Eureka相比,Dubbo在服务治理领域走的完全是不同的风格路线,我们从各个功能上先来做一个了解。

Dubbo的长连接

Eureka的注册中心在服务治理领域采用的是一种“佛系”的连接策略,比如服务发现和心跳检测,都是等待服务节点自己上报状态。而Dubbo相比较之下就是“事必躬亲”的管理策略,Dubbo的注册中心,服务提供者和服务消费者三者之间均为长连接,注册中心严密监测节点的状态变化。

Dubbo的注册中心基于长连接感知服务提供者的状态,假如服务提供者宕机,注册中心将立即推送事件通知消费者。但是注册中心自身宕机并不会影响已经上线运行的服务提供者和消费者。

服务剔除

当服务提供者出现异常情况的时候(比如电源又被挖掘机铲断了),注册中心利用长连接可以侦听到服务的不可用状态,进而在服务列表中删除服务提供者。

我们以Zookeeper注册中心为例,Dubbo的服务剔除原理实际上是利用Zookeeper的临时节点和会话保持的功能。ZK中的数据是和一个会话绑定的,一旦会话异常ZK就会清除这个会话创建的临时节点和所有订阅该会话的Watcher。

我们结合Dubbo的长连接和服务剔除机制,讲一讲ZK中的会话(Session)是怎么一回事儿。在ZK中当一个长连接建立起来后,会生成一个Session ID,这是一个全局唯一的标识符。在会话期间内ZK通过心跳感应连接状态,如果在会话过期时间内没有心跳发送过来,或者因为网络原因导致会话断掉,那么这个时候客户端就会重新选择新的ZK节点进行连接。因此,当会话过期时,Dubbo的服务提供者和消费者能自动恢复注册数据,重新订阅请求。

Eureka则不同,Eureka后台有一个服务自保的机制,也就是说短期的网络波动导致大比例节点无法连接到注册中心的时候,Eureka会开启自保模式,在这个模式下服务剔除功能将被禁用。

心跳检测

Dubbo同样也有心跳检测,它的目的是检测服务提供者和服务消费者之间的连接是否还处于可用状态。如果在默认60s没有消息进来的时候,会尝试发送一个心跳Request,如果连着180秒既没有消息也没心跳,那么则会关闭Channel,对于Consumer来说则需要重新连接一个新的Provider。

监控中心

服务提供者向注册中心注册其提供的服务,并汇报调用时间到监控中心。服务消费者向注册中心获取服务提供者地址列表,并根据负载算法直接调用提供者,同时汇报调用时间到监控中心。

监控中心是一个可选组件,可以根据自身项目需要决定是否接入。监控中心和各个节点之间并不是长连接,同时监控中心的宕机并不会影响任何服务调用,只不过可能会丢失一部分的监控数据而已。

Remoting模块主要负责远程调用,核心部分是Dubbo的协议栈实现,处于整个调用链路中相对底层的部分。我们在后面安排了单独一个小节来介绍Dubbo协议的细节,在这里我们简单的看下Remoting框架的接口结构。

顶层接口层

  • Endpoint 它是一个顶层的抽象接口,定义了获取网络端点地址、发送消息、获取通信Channel、关闭连接等一些列方法。
    • Channel - 它继承自Endpoint,但是扩展了操作Attribute的方法,比如常用的getAttribute,setAttribute等
  • ChannelHandler ChannelHandler定义了一系列接口用来处理五种不同的网络事件,分别对应connected、disconnected、sent、received和caught
  • Resetable 接口中只定义了一个方法reset,用来重置连接属性

AbstractPeer和AbstractChannel

AbstractPeer实现了上面提到的两个顶层接口,它是一种代理模式的组合结构,通过构造器接收一个ChannelHandler对象,然后把方法实现的具体逻辑委托给ChannelHandler对象来实现,随手拿一个接收消息的代码来举例:

@Override
public void received(Channel ch, Object msg) throws RemotingException {
    if (closed) {
        return;
    }
    handler.received(ch, msg);
}

AbstractChannel 添加了send方法(发送消息到远程服务)的缺省验证逻辑,作为NettyChannel等具体底层实现类的统一父类

Client & Server

Client 作为服务调用的发起方(消费者)的顶层接口,继承了Endpoint和Channel接口的同时,还定义了reconnect方法,用来重新连接到Server。Dubbo中的底层服务调用实现类(比如NettyClient和MinaClient)都继承自Client,但是Client只是个发起服务调用的壳,底层的调用逻辑都被封装在Channel对象里(AbstractChannel的子类,比如NettyChannel)

Server 作为服务提供方的顶层接口,继承自Endpoint和Resetable的同时,又定义了一系列服务端的接口方法,比如获取Channel列表或某个指定Channel

学习Tips:我们读书分为精读和泛读,学习也是一样,把精力花在重点知识的学习上。在整个微服务的大纲中,我们始终是围绕Spring Cloud作为主线,希望通过对SC核心组件的学习,能够将其应用到我们工作中的项目里,夯实微服务架构体系的实战应用,提升我们的架构能力。而Dubbo更多的是作为一种对照,让大家体会Dubbo和Eureka两种不同的服务治理理念。

·······················
更多精彩内容,欢迎关注课程:《Java架构师成长直通车》

点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消