1.5 实现微服务架构
本书的定位是讨论实现微服务架构的技术体系和工程实践。在前面各节内容中,我们已经对服务建模、服务拆分、服务集成进行了分析,并给出了构建微服务架构的基础组件和关键要素,这些内容体现了实现微服务架构的需求。接下来我们将围绕如何实现这些需求展开讨论,通过分析目前市面上主流的技术体系完成微服务架构实现技术选型。
1.5.1 微服务架构技术体系
本书将从两个维度对微服务架构技术体系进行描述,即实现技术维度和管理体系维度。
为了实现微服务,首先需要选择一种主流的工具来构建单个微服务。当系统中存在多个微服务时,我们就应该提供服务治理、负载均衡、服务容错、API网关、配置中心、事件驱动等实现方案以完成服务之间的交互和集成。
微服务架构管理体系包括如何对微服务进行测试,以及基于日志聚合和服务跟踪的服务监控管理。同时,服务安全对于微服务架构而言也提供了不同的实现策略和技术。最后,我们把服务的部署也归到管理体系之中。
1.5.2 微服务架构实现技术选型
实现微服务架构的第一步是进行技术选型,也就是选择一个合适的技术体系来支持微服务的开发工作。目前市面上并没有一个真正意义上实现微服务的技术体系,但还是存在一些可供参考的工具和框架。本书后续内容将使用Spring Cloud作为实现微服务的主体框架,本节将会给出选择该框架的原因,同时也会对其他同类框架进行分析和类比。
1. 技术选型的参考标准
所谓技术选型,首先需要明确选型的参考标准。结合前面的讨论,我们对于工具的选择也将围绕核心组件完备性和关键要素实现难度两方面来展开。
(1)核心组件完备性
微服务的核心组件由服务通信、事件驱动、负载均衡、服务路由、API网关和配置管理所组成。
• 服务通信
对于服务通信,微服务架构明确要求服务之间通过跨进程的远程调用方式进行通信。关于远程调用,有3种风格的解决方案,即RPC、REST和自定义实现。而在服务与服务的交互方式上,也存在两个维度,即按照交互对象的数量分为一对一和一对多,以及按照请求响应的方式分为同步和异步。目前RPC框架可供选型的余地很大,如Alibaba Dubbo、Facebook Thrift及Google gRPC等都是非常主流的实现,而REST的实现则包括Jersey和Spring MVC等。
• 事件驱动
事件驱动架构实现工具的表现形式通常是各种消息中间件,如实现JMS(Java Message Service,Java消息服务)规范的ActiveMQ、实现AMQP(Advanced Message Queuing Protocol,高级消息队列协议)规范的RabbitMQ、在大数据流式计算领域中应用非常广泛的Kafka,当然还有像Alibaba自研的RocketMQ。在这些消息中间件中,ActiveMQ一般不考虑,如果是相对比较轻量级的应用可以选择RabbitMQ,而Kafka则适合大型应用的场景。
• 负载均衡
负载均衡分为服务器端负载均衡和客户端负载均衡两大类实现方案。在服务器软件上,可以选择Nginx、HA proxy、Apache、LVS等工具。而Netflix Ribbon则是一种可以单独使用的负载均衡机制。事实上所有的分布式服务框架基本都内置了负载均衡的实现,所以负载均衡本身并不需要做太多的选择。
• API网关
API网关是微服务架构的核心组件之一。Netflix OSS(Open Source Software)中有一个Zuul提供了一套过滤器机制,可以很好地支持签名校验、登录校验等前置过滤功能处理,同时它也维护了路由规则和服务实例,以便完成服务路由功能。其他可供参考的API网关还有Mashape和开源的Kong等。
• 配置管理
配置管理的作用是完成集中式的配置信息管理。目前比较主流的包括Spring旗下的Spring Cloud Config、淘宝的Diamond和百度的Disconf等。在实现上,Spring Cloud Config支持配置服务放在配置服务的内存中(即本地),也支持放在远程Git仓库,这点与其他工具在设计上有较大不同。Diamond和Disconf都是基于MySQL作为存储媒介,Diamond采用拉模型,即每隔15秒拉一次全量数据;而Disconf基于Zookeeper的推模型,实时推送。在配置数据模型上,Diamond只支持Key-Value结构的数据,采用的是非配置文件模式;而Disconf支持传统的配置文件模式,也支持Key-Value结构数据。
(2)关键要素实现难度
关于微服务实现的关键要素,因为数据一致性更多是一种实现机制而不是具体工具,所以我们主要需要明确注册中心以及服务可靠性实现上的难度。
• 注册中心
关于服务注册和服务发现,比较常见的分布式一致性协议是Paxos协议和Raft协议。相比Paxos协议,Raft协议易于理解和实现,因此最新的分布式一致性方案大都选择Raft协议。我们知道Zookeeper采用的是基于Paxos协议改进的ZAB(Zookeeper Atomic Broadcast,Zookeeper原子消息广播)协议,而Raft协议的实现工具主要是Consul和Etcd。
注册中心是任何一个微服务框架所必不可少的组件,很多框架都内建了对服务注册中心的支持。例如,Alibaba的Dubbo框架支持包括Zookeeper、Redis等在内的多种注册中心实现,默认采用的是Zookeeper;新浪的Motan支持Zookeeper,也支持Consul;Spring Cloud同时提供了Spring Cloud Consul和Spring Cloud Zookeeper两种实现方案;而Netflix OSS中使用的是Eureka。
• 服务可靠性
服务可靠性相关的功能主要包括服务容错、服务隔离、服务限流和服务降级,其中大多数机制都偏向与实现策略而不是实现工具。我们需要明确的是如何实现服务隔离和服务熔断机制的框架。
服务熔断器目前只有一个可选的开源方案,那就是Netflix Hystrix。Netflix Hystrix同时也实现了服务隔离机制。本书后续章节会对该框架做详细分析。
2. 微服务实现框架对比
讲完微服务框架的选型标准以及所应该具备的核心组件和关键要素之后,下面来看一下目前业界有哪些现成的框架可供我们直接使用,这里列举了Dubbo和Spring Cloud这两个目前最主流的框架作为选型的基础。
(1)Dubbo
Dubbo是国内SOA框架集大成之作,基本具备一个SOA框架应有的所有功能,包括高性能通信、多协议集成、服务注册与发现、服务路由、负载均衡、服务治理等核心功能。作为一款RPC架构和SOA架构产品,Dubbo无疑是非常优秀的。但在功能完备性上,API网关、服务熔断器等核心组件在Dubbo中并没有完整体现。
在社区活跃度上,Dubbo自2012年底开始已基本不再更新,但这不影响其在各大互联网公司的应用和扩展,而且从2017年开始,阿里巴巴重新启动了Dubbo框架的维护工作。
Dubbo的文档可以说在国内开源框架中算是一流的,非常全面且讲解得比较深入,由于老版本已经非常稳定,所以也不太会出现不一致的情况,学习成本较低。
(2)Spring Cloud
Spring Cloud是Spring家族中新的一员,重点打造面向服务化的功能组件,在功能上服务注册中心、API网关、服务熔断器、分布式配置中心等组件都能在Spring Cloud中找到对应的实现。
在版本更新上,显然Spring Cloud也表现得非常活跃。目前Spring Cloud在Github的托管代码几乎每天都有更新,其发展仍处于高速迭代的阶段。
Spring Cloud在一定程度上是一种集成型的框架,其内部大量依赖于各种第三方工具和框架,所以文档在体量上自然要比Dubbo多很多,文档内容上还算简洁清楚,但是更多的是偏向整合,更深入的使用方法还是需要查看第三方组件的详细文档。
(3)对比与结论
通过对比分析,本书将选择Spring Cloud作为实现微服务架构的主体框架。功能的完备性是我们选择Spring Cloud的主要原因,表1-1中列出了Dubbo与Spring Cloud功能对比一览,可以看到Spring Cloud提供了很多Dubbo所不具备但对微服务实现又必不可少的核心组件。
表1-1 Dubbo与Spring Cloud功能一览
另一个选择Spring Cloud的原因在于服务之间的交互方式。我们知道微服务架构中推崇基于HTTP协议的RESTful风格实现服务间通信,而Dubbo的服务调用基于长连接的RPC实现。采用RPC方式会导致服务提供方与调用方接口产生较强依赖,而且服务对技术敏感,无法做到非常通用。Spring Cloud采用的就是RESTful风格,这方面更加符合微服务架构的设计理念。
Spring Cloud还具备一个天生的优势,因为它是Spring家族中的一员,而Spring在开发领域的强大地位给Spring Cloud起到很好的推动作用。同时,Spring Cloud基于Spring Boot,而Spring Boot目前已经在越来越多的公司得到应用和推广,用来简化Spring应用的框架搭建及开发过程。Spring Cloud也继承了Spring Boot简单配置、快速开发、轻松部署的特点,让原本复杂的架构工作变得相对容易上手。
通过以上分析,相信读者对Dubbo和Spring Cloud有了一个初步的了解。从目前Spring Cloud的被关注度和活跃度上来看,将来很有可能会成为微服务架构的标准框架,本书后续章节将对Spring Cloud的部分核心组件做详细讲解。