Ref: http://www.broadview.com.cn/article/348

微服务架构是当前很热门的一个概念,它不是凭空产生的,是技术发展的必然结果。虽然微服务架构没有公认的技术标准和规范草案,但业界已经有一些很有影响力的开源微服务架构平台,架构师可以根据公司的技术实力并结合项目的特点来选择某个合适的微服务架构平台,以此稳妥地实施项目的微服务化改造或开发进程。
本文选自《架构解密:从分布式到微服务》一书。
本文盘点了四种常用的微服务架构方案,分别是

  • ZeroC IceGrid
  • Spring Cloud
  • 基于消息队列
  • Docker Swarm

    1 ZeroC IceGrid 微服务架构

    ZeroC IceGrid 作为一种微服务架构,它基于 RPC 框架发展而来,具有良好的性能与分布式能力,如下所示是它的整体示意图。
    微服务架构方案 - 图1
    IceGrid 具备微服务架构的如下明显特征。
    首先,微服务架构需要一个集中的服务注册中心,以及某种服务发现机制。IceGrid 服务注册采用 XML 文件来定义,其服务注册中心就是 Ice Registry,这是一个独立的进程,并且提供了 HA 高可用机制;对应的服务发现机制就是命名查询服务,即 LocatorService 提供的 API,可以根据服务名查询对应的服务实例可用地址。
    其次,微服务架构中的每个微服务通常会被部署为一个独立的进程,当无状态服务时,一般会由多个独立进程提供服务。对应在 IceGrid 里,一个 IceBox 就是一个单独的进程,当一个 IceBox 只封装一个 Servant 时,就是一个典型的微服务进程了。
    然后,微服务架构中通常都需要内嵌某种负载均衡机制。在 IceGrid 里是通过客户端 API 内嵌的负载均衡算法实现的,相对于采用中间件 Proxy 转发流量的方式,IceGrid 的做法更加高效,但增加了平台开发的工作量与难度,因为采用各种语言的客户端都需要实现一遍负载均衡的算法逻辑。
    最后,一个好的微服务架构平台应该简化和方便应用部署。我们看到 IceGrid 提供了 grid.xml 来描述与定义一个基于微服务架构的 Application,一个命令行工具一键部署这个 Application,还提供了发布二进制程序的辅助工具 ——icepatch2。下图显示 icepatch2 的工作机制,icepatch2server 类似于 FTP Sever,用于存放要发布到每个 Node 上的二进制代码与配置文件,而位于每个 Node 上的 icepatch2client 则从 icepatch2server 上拉取文件,这个过程中采用了压缩传输及差量传输等高级特性,以减少不必要的文件传输过程。客观地评价,在 Docker 技术之前,icepatch2 这套做法还是很先进与完备的,也大大减少了分布式集群下微服务系统的运维工作量。
    微服务架构方案 - 图2
    如果基于 IceGrid 开发系统,则通常有三种典型的技术方案,下图展示了这三种技术方案。
    微服务架构方案 - 图3
    其中方案一是比较符合传统 Java Web 项目的一种渐进改造方案,Spring Boot 里只有 Controller 组件而没有数据访问层与 Service 对象,这些 Controller 组件通过 Ice RPC 方式调用部署在 IceGrid 里的远程的 Ice 微服务,面向前端包装为 REST 服务。此方案的整体思路清晰,分工明确。Leader 在开源项目中给出了这种方式的一个基本框架以供参考:https://github.com/
    MyCATApache/mycat-ice。
    方案二与方案三则比较适合前端 JavaScript 能力强的团队,比如很擅长 Node.js 的团队可以考虑方案二,即用 JavaScript 来替代 Spring Boot 实现 REST 服务。主要做互联网 App 的系统则可以考虑方案三,浏览器端的 JavaScript 以 HTML5 的 WebSocket 技术与 Ice Glacier2 直接通信,整体高效敏捷。
    IceGrid 在 3.6 版本之后还增加了容器化的运行方式,即 Ice Node 与 Ice Registry 可以通过 Docker 容器的方式启动,这就简化了 IceGrid 在 Linux 上的部署。对于用 Java 编写的 Ice 微服务架构系统,我们还可以借助 Java 远程类加载机制,让每台 Node 自动从某个远程 HTTP Server 下载指定的 Jar 包并加载相关的 Servant 类,从而实现类似 Docker Hub 的机制。下图显示了前面提到 mycat-ice 开源项目时给出的具体实现方案。
    微服务架构方案 - 图4

    2 Spring Cloud 微服务架构

    Spring Cloud 是基于 Spring Boot 的一整套实现微服务的框架,因此它只能采用 Java 语言,这是它与其他几个微服务框架的最明显区别。Spring Cloud 是一个包含了很多子项目的整体方案,其中由 Netflix 开发后来又并入 Spring Cloud 的 Spring Cloud Netflix 是 Spring Cloud 微服务架构的核心项目,即可以简单地认为 Spring Cloud 微服务架构就是 Spring Cloud Netflix,后面我们用 Spring Cloud 时如果不特意声明,就是指 Spring Cloud Netflix。
    首先,Spring Cloud 中的服务注册中心是 Eureka 模块,它提供了一个服务注册中心、服务发现的客户端,还有一个简单的管理界面,所有服务使用 Eureka 的服务发现客户端来将自己注册到 Eureka 中,如下所示为相关示意图,你会发现它很像之前第 4 章中的某个图。
    微服务架构方案 - 图5
    那么 Spring Cloud 是如何解决服务的负载均衡问题的呢?由于 Spring Cloud 的微服务接口主要是基于 REST 协议实现的,因此它采用了传统的 HTTP Proxy 机制。如下图所示,Zuul 类似一个 Nginx 的服务网关,所有客户端请求都通过这个网关来访问后台的服务。
    微服务架构方案 - 图6
    Zuul 从 Eureka 那里获取服务信息,自动完成路由规则的映射,无须手工配置,比如上图中的 URL 路径 /customer/* 就被映射到 Customer 这个微服务上。当 Zuul 转发请求到某个指定的微服务上时,会采用类似 ZeroC IceGrid 的客户端负载均衡机制,被称为 Ribbon 组件,下图给出了 Zuul 与 Eureka 的关系及实现服务负载均衡的示意图。
    微服务架构方案 - 图7
    如下所示是 Spring Cloud 微服务架构平台的全景图。我们看到它很明显地继承了 Spring Framework 一贯的思路 —— 集大成!
    微服务架构方案 - 图8
    从图中来看,Spring Cloud 微服务架构平台集成了以下一些实际项目开发中常用的技术与功能模块。
    基于 Spring Security 的 OAuth 模块,解决服务安全问题。
    提供组合服务(Composite Services)的能力。
    电路断路器 Hystrix,实现对某些关键服务接口的熔断保护功能,如果一个服务没有响应(如超时或者网络连接故障),则 Hystrix 可以在服务消费方中重定向请求到回退方法(fallback method)。如果服务重复失败,则 Hystrix 会快速失败(例如直接调用内部的回退方法,不再尝试调用服务),直到服务重新恢复正常。
    监控用的 Dashboard,可以简化运维相关的开发工作量。
    总体来说,Spring Cloud 是替代 Dubbo 的一种好方案,虽然 Spring Cloud 是基于 REST 通信接口的微服务架构,而 Dubbo 以 RPC 通信为基础。对于性能要求不是很高的 Java 互联网业务平台,采用 Spring Cloud 是一个门槛相对较低的解决方案。

    3 基于消息队列的微服务架构

    除了标准的基于 RPC 通信(以及类 RPC 的通信如 Http Rest、SOAP 等)的微服务架构,还有基于消息队列通信的微服务架构,这种架构下的微服务采用发送消息(Publish Message)与监听消息(Subscribe Message)的方式来实现彼此之间的交互。下图是这种微服务架构下各个组件之间的交互示意图,我们看到消息中间件是关键,它负责连通各个微服务与 UI 组件,担任了整个系统互联互通的重任。
    微服务架构方案 - 图9
    基于消息队列的微服务架构是全异步通信模式的一种设计,各个组件之间没有直接的耦合关系,也不存在服务接口与服务调用的说法,服务之间通过消息来实现彼此的通信与业务流程的驱动,从这点来看,基于消息队列的微服务架构非常接近 Actor 模型。实际上,分布式的 Actor 模型也可以算作一种微服务架构,并且在微服务概念产生之前就已经存在很久了。下面是一个购物网站的微服务设计示意图,我们看到它采用了基于消息队列的微服务架构。
    微服务架构方案 - 图10
    网易的蜂巢平台就采用了基于消息队列的微服务架构设计思路,如下图所示,微服务之间通过 RabbitMQ 传递消息,实现通信。
    微服务架构方案 - 图11
    与上面几种微服务架构相比,基于消息队列的微服务架构并不多,案例也相对较少,更多地体现为一种与业务相关的设计经验,各家有各家的实现方式,缺乏公认的设计思路与参考架构,也没有形成一个知名的开源平台。因此,如果需要实施这种微服务架构,则基本上需要项目组自己从零开始去设计实现一个微服务架构基础平台,其代价是成本高、风险大,因此决策之前需要架构师 “接地气” 地进行全盘思考与客观评价。

    4 Docker Swarm 微服务架构

    Docker Swarm 其实是 Docker 公司 “高仿” Google 开源的 Kubernetes 微服务架构平台的一个产品,但一直无法跟上对手的脚步,在业界始终缺乏影响力。2016 年发布 Docker 1.12 时,Docker Swarm 就被强行集成到了 Docker Engine 中而不再作为单独的工具发布了,这类似当年微软推广 IE 浏览器的做法。不过即使这样,也难以掩盖 Docker Swarm 还没成名就已经陨落的事实。
    Docker Swarm 的最初目标是将一些独立的 Docker 主机变成一个集群,如下图所示,我们通过简单的 Docker 命令行工具就能创建一个 Swarm 集群。
    微服务架构方案 - 图12
    后来随着 Kubernetes 微服务架构平台越来越火,Docker 公司开始努力让 Swarm 向着 Kubernetes 的方向靠拢,即变成一个基于容器技术的微服务平台。下面给出了 Swarm 集群的结构图。
    微服务架构方案 - 图13
    从图中我们看到一个 Swarm 集群中有两种角色的节点。
    Swarm Manager:负责集群的管理、集群状态的维持及调度任务(Task)到工作节点(Swarm Node)上等。
    Swarm Node:承载运行在 Swarm 集群中的容器实例,每个 Node 主动汇报其上运行的任务(Task)并维持同步状态。
    上图中的 Docker Compose 是官方编排(Orchestration)项目,它提供了一个 YAML 格式的文件,用于描述一个容器化的分布式应用,并且提供了相应的工具来实现一键部署的功能。下图给出了两节点的 Couchbase 集群对应的 YAML 文件定义,此 Couchbase 集群随后被部署到了 Swarm 集群中的两个 Node 节点上。
    微服务架构方案 - 图14
    注意上图左边 YAML 文件中的 Services 定义,Swarm manager 节点给每个 Service 分配唯一的 DNS 名字,因此可以通过最古老又简单的 DNS 轮询机制来实现服务的发现与负载均衡,这明显借鉴了 Kubernetes 的做法。
    由于 Docker Swarm 高仿了前辈 Kubernetes 的设计,而且在微服务架构中并没有太多的影响力,所以我们在此并未做深入介绍,在《架构解密:从分布式到微服务》一书中将会重点介绍 Kubernetes 微服务平台。