课程名称:Java架构师-技术专家
课程章节:第25周 服务治理的另一条路 - Dubbo
主讲老师:慕课讲师团:Geely、风间影月、阿神……
课程内容:
1、 Dubbo 核心功能 ——Registory 模块
Registory 是Dubbo中负责服务注册的模块,也就是我们熟悉的注册中心,目前 Dubbo支持五种不同类型的注册中心,其中使用最多的就是 Zookeeper 了。
Zookeeper 是 Apache Hadoop 的子项目,它底层是一个树形的目录结构,同时支持基于发布定于模型的变更推送,这个特性特别适合应用在注册中心服务上。
1.1、 注册中心的运作方式
注册中心只承担服务治理相关的功能(注册、发现、心跳和下线等),它不承担消息的转发(这一点和 Eureka一样),因此不用承担访问压力。和Eureka相比,Dubbo’在服务治理领域走的是完全不同的风格路线。
1.2、Dubbo 的长连接
Eureka的注册中心在服务治理领域采用的是一种 “佛系“的连接策略,比如服务发现和心跳检测,都是等待服务节点自己上报状态。而Dubbo相比较之下就是 ”事必恭亲“的管理策略,Dubbo的注册中心,服务提供者和服务消费者三者之间均为长连接,注册中心严密检测节点的状态变化。
Dubbo的注册中心基于长连接感知服务提供者的状态,例如服务提供者宕机,注册中心将立即推送事件通知消费者。但是注册中心自身宕机并不会影响已经上线运行的服务提供者和消费者。
1.3、服务剔除
当服务提供者出现异常情况的时候,注册中心利用长连接可以侦听到服务的不可用状态,进而在服务列表中删除服务提供者。
我们以Zookeeper注册中心为例,Dubbo的服务剔除原理实际上是利用Zookeeper的临时节点和会话保持的功能。ZK中的数据是和一个会话绑定的,一旦会话异常ZK就会清除这个会话创建的临时节点和所有订阅该会话的Watcher。
我们结合Dubbo的长连接和服务剔除机制,讲一讲ZK中的会话(Session)是怎么一回事儿。在ZK中当一个长连接建立起来后,会生成一个Session ID,这是一个全局唯一的标识符。在会话期间内ZK通过心跳感应连接状态,如果在会话过期时间内没有心跳发送过来,或者因为网络原因导致会话断掉,那么这个时候客户端就会重新选择新的ZK节点进行连接。因此,当会话过期时,Dubbo的服务提供者和消费者能自动恢复注册数据,重新订阅请求。
Eureka则不同,Eureka后台有一个服务自保的机制,也就是说短期的网络波动导致大比例节点无法连接到注册中心的时候,Eureka会开启自保模式,在这个模式下服务剔除功能将被禁用。
1.4、心跳检测
Dubbo同样也有心跳检测,它的目的是检测服务提供者和服务消费者之间的连接是否还处于可用状态。如果在默认60s没有消息进来的时候,会尝试发送一个心跳Request,如果连着180秒既没有消息也没心跳,那么则会关闭Channel,对于Consumer来说则需要重新连接一个新的Provider。
1.5、 监控中心
服务提供者向注册中心注册其提供的服务,并汇报调用时间到监控中心。服务消费者向注册中心获取服务提供者地址列表,并根据负载算法直接调用提供者,同时汇报调用时间到监控中心。
监控中心是一个可选组件,可以根据自身项目需要决定是否接入。监控中心和各个节点之间并不是长连接,同时监控中心的宕机并不会影响任何服务调用,只不过可能会丢失一部分的监控数据而已。
3、Remoting 模块
Remoting模块主要负责远程调用,核心部分是Dubbo的协议栈实现,处于整个调用链路中相对底层的部分。我们在后面安排了单独一个小节来介绍Dubbo协议的细节,在这里我们简单的看下Remoting框架的接口结构。
2.1、顶层接口层
- EndPoint :它是一个顶层的抽象接口,定义了获取网络端点地址、发送消息、获取通信Channel、关闭连接等一些列方法。
- Channel: 它继承自Endpoint,但是扩展了操作Attribute的方法,比如常用的getAttribute,setAttribute等
- ChannelHandler定义了一系列接口用来处理五种不同的网络事件,分别对应connected、disconnected、sent、received和caught
- 接口中只定义了一个方法reset,用来重置连接属性
2.2、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等具体底层实现类的统一父类
2.3、Client & Server
** Client** 作为服务调用的发起方(消费者)的顶层接口,继承了Endpoint和Channel接口的同时,还定义了reconnect方法,用来重新连接到Server。Dubbo中的底层服务调用实现类(比如NettyClient和MinaClient)都继承自Client,但是Client只是个发起服务调用的壳,底层的调用逻辑都被封装在Channel对象里(AbstractChannel的子类,比如NettyChannel)
Server 作为服务提供方的顶层接口,继承自Endpoint和Resetable的同时,又定义了一系列服务端的接口方法,比如获取Channel列表或某个指定Channel
3、 有哪些可选的注册中心
4、Dubbo在Zookeeper 中的存储
学习收获:
今天学习了
- Dubbo 的Registroy
- Remoting 模块。
- Dubbo可以主要使用的注册中心有Zookeeper和Nacos
- Dubbo 在Zookeeper 的存储结构
对Dubbo 注册中心原理和远程调用原理有了大致了解