开篇词:论技术原理的相通性

开篇词:论技术原理的相通性

从今天开始,我将和大家一起全面梳理互联网分布式系统开发的核心机制。我们会结合 Dubbo、Spring Cloud、Mybatis 等主流开源框架来介绍分布式开发的各个主题,并通过源码分析的方式帮忙大家理解和掌握这些开源框架背后的技术原理和应用。

在此之前,作为整个课程的开篇,我们将通过一些案例来阐述一个核心观点,即技术原理之前存在相通性。这个核心观点是促使这个课程诞生的动机,同时也是我们学习的方向和目标。

测试:从几道面试题看看你对技术原理的掌握程度

以下是笔者在阿里巴巴、网易、蘑菇街等一些国内大型互联网公司面试时碰到的几道面试题,供大家参考:

  • 微内核架构模式的特点、实现方式及应用场景?

  • 如何理解代理模式在远程方法调动中的作用?

  • RPC 架构核心组件、Dubbo 框架原理?

  • 微服务架构中注册中心、配置中心的设计和实现方法?

  • 如何实现一个轻量级的客户端负载均衡机制?

  • 如何在设计系统时预留可扩展点?

关于这些面试题的具体回答思路以及所涉及的知识体系我们在本课程中都会具体展开,在这里列举这些面试题的目的在于引出一个话题,即面对这些看上去比较抽象而复杂的问题时,我们应该如何应对?

很多读者可能对以上问题有一定的了解,有些则可能连题目的意思都无法正确把握。但对于那些能够回答这些问题的人而言,知道的可能也仅仅是针对这些问题的答案,也就是说对于已经接触过或使用过的工具框架而言肯定多少能明白其中的原理,但是如果是那些没有用过的工具和框架呢?

工具和框架发展日新月异,例如在我们的课程中会经常提到的 Dubbo 框架在 2013 年开始已经几乎不再更新,而这两年又重新启动维护工作,目前已经成为 Apache 的顶级项目。不难想象在不久的将来,业界还会出现第二个、第三个类似 Dubbo 这样的框架。我们知道 Dubbo 是阿里巴巴开源的一个分布式服务框架,其背后的核心原理就是实现了 RPC 和服务治理。对于任何一个分布式服务框架而言,RPC 和服务治理都是不可缺少的组件,而关于 RPC 和服务治理的相关设计方法和实现原理在很长一段时间内实际上都没有什么变化。我们只要能够对 RPC 和服务治理有深刻的理解,那么关于 Dubbo 同类型的任何新框架,如果出现类似“RPC 架构核心组件、Dubbo 框架原理”这样的面试题,我们都应该有明确的回答思路和方法。为了达到这样的境界,这就要引出本篇的核心主题,即技术知识体系之间存在一定的相通性。我们将通过具体示例来阐述和论证这一观点。

论技术原理的相通性示例之一:RPC 架构

关于 RPC 架构的组成有一定的固定结构,一般认为包括网络通信、序列化 / 反序列化、传输协议和服务调用等四个组件,而我们也知道 RPC 架构是构成分布式服务架构和微服务架构的基本结构。对于服务的提供者和调用者而言,RPC 架构表现为一种对称结果(见下图)。

00.01

对于常见的分布式系统而言,RPC 架构的应用非常常见,因为后面的课程中会有详细讨论,所以这里不对上图做具体展开。从技术原理的相通性上讲,我们这里要讲的是它在另一个领域,即大数据体系中的应用。以 Hadoop 为代表的大数据生态系统中的大多数工具本质上也表现为一种分布式系统,也需要 RPC 架构这样的远程通信工具实现各个节点组件之间的协作和管理。

我们来分析一下 Hadoop 中的 RPC 实现机制。 Hadoop 采用了 RpcEngine 接口封装了 RPC 的整个调用过程,RpcEngine 接口提供了多个实现类,包括 WritableRpcEngine(见下图中的左半部分)和 ProtobufRpcEngine(见下图中的右半部分)。WritableRpcEngine 使用 Hadoop 自带的 Writable 序列化机制实现远程调用过程中的序列化,包括 Invoker 类、Invocation 类和 Server 类等三个核心类。Invoker 是 Java 动态代理核心接口 InvocationHandler 的实现类,用于序列化并生成 Invocation 对象并将 Invocation 对象发送到远程服务器,同时获取响应并反序列化。而 Invocation 类代表 RPC 请求对象,包括方法、参数等调用信息。最后的 Server 类启动 Socket 监听 RPC 请求,调用 WritableRpcInvoker 响应请求。这里的 WritableRpcInvoker 负责响应远程客户端请求,发送序列化请求,并通过反射调用服务端程序并包装结果对象。另一方面,在 ProtobufRpcEngine 中,Invoker 的序列化 / 反序列化工具使用 Protobuf,并使用 RPCRequest/ResponseWrapper 包装 RPC 请求。而 ProtobufRpcInvoker 与 WritableRpcInvoker 的主要区别就是序列化 / 反序列化方式的不同。

00.02

Hadoop RPC 客户端请求流程如下图所示,从下图中我们不难看到很多熟悉的名称,包括 Proxy、Invoker、Protocol 等,这些名词在 RPC 对称架构图中都有所体现。可以看到整个请求过程也是一个比较标准的动态代理实现方式,作为一种通用性实现机制,代理模式及其应用场景也在本课程中会有详细展开。

00.03

在这个案例中,我们看到了动态代理、序列化、服务发布和引用等 RPC 架构中通用的技术体系,如果你已经掌握了这些知识点,那么就算没有具体分析过 Hadoop 中实现远程通信的过程,你也应该能够通过这些通用技术体系构建对 Hadoop RPC 的理解模型并在具体的面试过程中表现出对这块内容的理解程度。

论技术原理的相通性示例之二:分布式协调

在本课程中,我们会基于 Dubbo 介绍注册中心这一服务化架构中的基础组件。而讲到注册中心就不得不提及分布式协调。对于分布式协调,我们需要了解到的是它不仅仅可以实现注册中心,还可以适用于很多场景。对于这些不同的场景,我们只需要把握针对分布式协调的基本知识体系,分析原理和解决问题的思路都是高度一致的。

分布式协调实现的主流工具是 Zookeeper,其核心是一个精简的文件系统,提供基于目录节点树方式的数据存储。Zookeeper 的基本组成结构是 ZNode,表示路径的同时也能存储数据,所有的 ZNode 通过路径被引用。一方面 ZNode 能够做到原子性访问,即所有请求的处理结果在整个 Zookeeper 集群中的所有机器是一致的。同时也能确保顺序(Sequential)性访问,从同一客户端发起的事务请求,会按照其发起顺序严格的应用到 Zookeeper 中去。

同时,Zookeeper 有两个特性与分布式协调直接相关。首先是它的会话(Session)机制。会话是客户端和服务器端的 TCP 连接,能够发送请求并接收 Watcher 事件。从类型而言,会话又可以分为短暂(Ephemeral)性会话和持久(Persistent)会话两种,前者在会话断开的同时会自动删除会话对应的 ZNode,而后者则不会。然后,对于每个 ZNode,Zookeeper 都提供了 Watcher 机制。Watcher 机制本质上就是分布式的回调,ZNode 的客户端关注 ZNode 发生的变化,一旦发生变化则回传消息到客户端,然后客户端的消息处理函数得到调用。在 Zookeeper 中,任何读操作都能够设置 Watcher。

基于 Zookeeper 的分布式协调机制,我们也可以实现与 Dubbo 中注册中心类似的共享存储方案。在注册中心中,所有服务在指定路径服务根目录下创建临时节点,所有访问这些服务的客户端监听该目录。当有新节点加入时,Zookeeper 实时通知到所有客户端,客户端做相应路由信息维护;而当某个节点宕机时,客户端通过 Watcher 同样会收到通知。整个流程的示意图见下图。关于 Dubbo 中如何集成 Zookeeper 以构建强大的注册中心,我们在课程的后续篇章中会有详细介绍。

00.04

有了会话和 Watcher 机制,我们就可以实现如下图所示的分布式环境下配置信息共享管理。在图中,通过监控“/Configuration”节点,我们就可以实时获取该节点下的配置数据并更新位于客户端的本地数据。

00.05

最后,我们再来看一下分布式锁的实现。在 Zookeeper 中,整个分布式锁的实现流程参考下图,可以看到核心的原理还是依赖于临时节点和 Watcher 机制。

00.06

通过以上讨论可以得出的结论是:不同场景表现出不同的需求,但这些需求的背后却可以通过同一种技术体系进行分析并解决。以分布式协调为例,Zookeeper 的临时节点和 Watcher 机制提供了一套可用于多种不同场景的统一解决方案。通过掌握其中的基本原理,我们面对自己并不熟悉但又类似的场景时就能得出正确的解决方案。

小结与预告

以上就是技术原理相通性的两个典型案例,在分布式系统开发技术中,这样的案例还有很多,我们会在整个课程中进行交叉讲解,并提供相应的学习方法和技巧。站在课程学习的角度上,我们也希望读者能够以理解技术原理相通性作为目标进行持续的学习和提升。

从下一篇开始,我们将进入整个课程的第一大部分,即剖析框架代码的结构的系统方法。当我们拿到 Dubbo、Spring Cloud 等开源框架之后,如何来分析这些框架的代码结构,并从中吸收框架级别的设计方法和技巧呢?让我们来一起看一下。

上一篇
下一篇