本文首先介绍系统架构演变的几个阶段;然后介绍微服务框架Dubbo和Spring Cloud,以及服务网格istio;最后介绍Duboo、SpringCloud、Istio三者之间的区别。
系统架构的发展阶段
1.1.1 单体应用阶段
在互联网发展的初期,用户数量少,一般网站的流量也很少,但硬件成本较高。因此,一般的企业会将所有的功能都集成在一起开发一个单体应用,然后将该单体应用部署到一服务器上即可满足业务需求。
虽然单应用是最初的架构,但目前它并没有消失,还在不停发展和演进,依然拥有巨大的市场。例如,现在有些采用MVC、MVP、MVVM开发的单体应用程序依然火爆,仍能够满足实际业务需求。
1.单体应用的优点。
- 易于集中式开发、测试、管理、部署。
- 无需考虑跨语言。
- 能避免功能重复开发(相对微服务)。
2.单体应用的缺点
- 团队合作困难。
- 代码维护、重构、部署都比较难。
- 稳定性、可用性(停机维护)、扩展性不高。
- 需要绑定某种特定的开发语言。
当用户规模越来越大时,单体应用可以通过集群来应对。比如,可以通过DNS、Nginx或硬件(F5)分配集群中的服务器来提供服务。但是,它的缺点(开发效率低、可维护性差、稳定性差)导致需要对单体应用进行拆分,比如做垂直拆分。
1.1.2 垂直应用阶段
为了应对更高的并发、业务需求和解决单体应用的缺点,需要根据业务功能对单体应用的架构方法进行演进,比如,可以将1.1.1中的单体应用的3个功能拆分为3个系统来提供服务,如图:
优点:
- 拆分后的系统可以解决高并发、资源按需分配的问题。
- 可以针对不同的模块进行优化和资源分配,便于水平扩展、实现负载均衡、提高容错性,实现了系统间的相互独立。
拆分应用有两种方式:水平拆分和垂直拆分。
1.水平拆分
水平拆分是指根据业务来拆分应用。例如,原应用中包含订单、会员两个部分,如果水平拆分则可以将其拆分成订单系统和会员系统。
其优点是:拆分后保证业务之间的相互影响较小,能合理地分配硬件资源(不同的业务对流量和性能的要求是不一样的)。但是这样可能会导致整个系统存在“重复造轮子”的问题,而且难于维护。
2.垂直拆分
垂直拆分是根据调用方法对系统进行拆分。比如,会员系统可以垂直拆分为普通用户和企业用户。
这样做的优点是:1.能按需分配资源和流量,各个垂直调用之间互不影响。2.可以通过配置进行上游调用的升级或降级。
缺点是:几乎完全“重复造轮子”。
对于垂直应用我们需要把握一个原则——分层,即“分层”设计和开发。例如,用于加速前端页面开发的MVC分层模式等是关键。
垂直应用除“重复造轮子”这个缺点外,还会增加系统之间的调用管理。如果某个系统的端口号或者IP地址发生变化,则需要手动修改调用方的配置信息。而且,在系统拆分后,通过搭建集群来实现负载均衡是比较复杂的。所以又演进出了分布式系统。
1.1.3 分布式系统阶段
在分布式系统中,各个小系统之间的交互式不可避免的,此时可将核心业务作为独立的服务抽取出来,逐渐形成稳定的基础服务,这样可以使前端的业务系统能更快速地响应复杂多变的市场需求。
其优点是:对基础服务进行了抽取,服务之间可以相互调用,从而提高了代码的复用和开发效率。此时,提高业务复用和整合分布式调用(RPC)是关键。
其缺点是:业务间耦合度变高;调用关系错综复杂;系统难以维护;在搭建集群后,很难实现负载均衡。
针对分布式系统存在的问题,可以通过治理基础服务来解决。
1.1.4 服务治理阶段
随着服务数量的不断增加,服务中的资源浪费和调度问题日益突出。此时需要增加一个调度中心来治理服务。调度中心可基于访问压力来实时管理集群的容量,从而提高集群的利用率。
在服务治理(SOA)架构中,需要一个企业服务总线(ESB)将基于不同协议的服务节点连接起来,它的工作是转换、解释消息和路由。服务治理架构如图:
SOA解决了以下问题:
- 服务间的通讯问题:引入了ESB、技术规范、服务管理规范,从而解决了不同服务间的通信问题。
- 基础服务的梳理问题:以ESB为中心梳理和规整分布式服务。
- 业务的服务化问题:以业务为驱动,将业务单元封装到服务中。
- 服务的可服用问题:将业务功能设计为通用的业务服务,以实现业务逻辑的复用。
随着业务复杂性、需求多变性和用户规模的不断增长,敏捷开发和DevOps(一种过程、方法的统称,用于促进开发、运维和质量保证部门之间的沟通、合作和整合)变得特别重要。
敏捷开发和DevOps在尽可能满足需求的同时,保证了良好的软件质量、系统可用性。敏捷交付和DevOps的要求催生了微服务架构的出现。
微服务采用的服务(治理)中心,而不是在SOA架构中“中心化”的ESB。因此,服务的调用不再需要知道“服务提供者”的IP地址、端口号,而只需要知道在服务中心中注册了的服务名即可。
1.1.5 微服务阶段
微服务(Microservices)架构是指:将系统的业务功能划分为极小的独立微服务,每个微服务只关注于完成某个小的任务。系统中的单个微服务可以被独立部署和扩展,且各个微服务之间是高内聚、低耦合的。微服务之间采用轻量化通信机制暴露接口来实现通信。
一个简单的微服务架构:
1.1.6 服务网格阶段
1. 什么是服务网格
服务网格(Service Mesh) 独立于服务之外运行,是服务间通信的基础设施层。服务网格类似于在每个服务上粘贴的功能模块。
如下图:
从上图可以看出,服务之间通过Sidecar(边车)进行通信,所有Sidecar和网络连接就形成了Service Mesh。Sidecar主要负责服务发现和容错处理。
服务网格主要由数据平台(Data Plane)和控制平台(Control Plane)组成。
- 数据平台:处理服务间的通信,并实现服务发现、负载均衡、流量管理、健康检查等功能。
- 控制平台:管理并配置Sidecar,以执行策略和收集数据。
服务网格架构与微服务架构的区别:
- 侧重点不同。微服务架构主要关注服务间的生态,例如服务治理等;而服务网格架构则更加关注服务之间的通信,以及与DevOps的结合。
- 侵入性不同。微服务架构实现了服务间的解耦,服务网格则实现了服务框架与服务框架之间的解耦。在微服务架构中,服务提供者和服务消费者需要配置“服务中心”的IP地址和端口号等配置信息(在使用Consul和Docker时,则不需要添加IP地址和端口号)。
服务网格是在服务之外独立运行的模块,它提供了微服务框架功能,服务不需要在代码和配置中添加相应的依赖库和依赖配置项。
2. 特点
- 对服务没有入侵性。
- 是应用程序间通信的一个中间层。
- 是一个轻量级的网络代理。
- 应用程序对服务网格无感知。
- 能够解耦应用程序的重试、监控、追踪和服务发现。
3. 主流的开源项目
Service Mesh 开源软件有:Linked、Envoy、Conduit(由开发Linkerd的公司开发)、Istio、nginMesh、Kong、Linkerd2(不同于Linkerd,它基于Rust和Go,没有JVM等大内存的开销)。其中Istio较为流行和著名。
1.2.1 主流微服务框架
如下表:
框架名称 | 说明 |
---|---|
Dubbo | 阿里巴巴开源的RPC框架 |
Dubbox | 当当基于Dubbo开源的RPC框架 |
String Cloud | Pivotal Software公司开源的微服务框架 |
Motan | 分布式远程服务调用(RPC)框架。它支持通过Spring配置方式集成;支持集成Consul、Zookeeper等配置服务组件;支持动态自定义负载均衡、跨机房流量调整等高级服务调度功能 |
Thrift | 用来进行可扩展且跨语言开发的软件框架,结合了软件堆栈和代码生成引擎 |
MSEC | QQ后台团队开源的框架,集RPC、名字发现服务、负载均衡、业务监控、灰度发布、容量管理、日志管理、Key-Value存储于一体 |
Hessian | 轻量级的RPC框架,基于HTTP协议传输,使用Hessian二进制序列化 |
Service Fabric | 微软开发的一个微服务框架 |
Lagom | 用于在java或scala中构建响应式微服务系统 |
Steeltoe | 使得.NET开发人员可以利用Steeltoe构建弹性微服务系统 |
Apollo | Spotify的Apollo(非百度和携程同名Apollo)用于编写可组合微服务的java库 |
Netflix OSS | Netflix 为大规模解决分布式系统问题而编写的一组框架和库 |
Kubernetes | 可以用它 的注册发现功能来构建微服务系统。更多的时候,它被用作DevOps的运维自动化工具 |
1.2.2 Dubbo
1. Dubbo简介
Dubbo致力于提高性能和透明化的远程服务调用方案和SOA服务治理方案。
Dubbo也是采用了Spring的配置方式。它基于Spring的可扩展机制(Schema)可透明化接入应用,对应用没有API入侵,支持API调用方式(官方不推荐)。只需用Spring加载Dubbo的配置即可。
2. Dubbo 核心功能
-
面向接口的高性能RPC(远程调用,使得用户可以像调用本地方法那样调用远程机器上的方法)调用。
提供了高性能的、基于代理的远程调用功能,服务以接口为粒度,为开发人员屏蔽了远程调用的底层细节。 -
智能负载均衡
内置了多种负载均衡策略,能智能感知节点的健康状况,可以有效地减少调用延迟,提高系统的吞吐量。 -
服务的自动注册与发现
支持多种注册服务方式,能对服务实例的上下线进行实时感知。 -
高度的可扩展
遵循“微内核+插件”设计原则,所有的核心功能(如 Protocol、transport、Serialization)都被设计为扩展点。 -
运行期流量调度
内置了条件、脚本等路由策略。通过不同的路由规则,可以方便地实现灰度发布、同机房优先等运行期的流量调度。 -
可视化的服务治理与运维
提供了丰富的服务治理、运维工具,可以随时查询服务的元数据、服务的健康状态和调用统计信息,实时下发路由策略,调整配置参数。
1.2.3 Sprng Cloud
- Spring Cloud 简介
Spring Cloud是基于Spring boot 的一个快速开发微服务的框架。它提供了一下开发微服务所需的一些常见组件。
- 服务发现(Service Discovery)
- 断路器(Circuit Breakers)
- 智能路由(Intelligent Routing)
- 微代理(Micro-Proxy)
- 控制总线(Control Bus)
- 一次性令牌(One-time Tokens)
- 全局锁(Global Locks)
- 领导选举(Leadership Election)
- 配置管理(Configuration Management)
- 分布式会话(Distributed Sessions)
- 集群状态(Cluster State)
Spring Cloud 负责管理这些可以独立部署、水平扩展和独立访问(或者有独立的数据库)的服务单元。
Spring Cloud 使得构建大型系统变得非常容易和低成本。小型项目可以采用Spring boot进行架构,当需要升级到微服务架构时,可以使用Spring Cloud 方便地对其进行升级。
2.Spring Cloud 的核心功能
- 分布式、版本化配置
通过Spring Cloud Config(或其他配置管理工具)来统一管理服务配置。我们可以将所有服务的配置文件放置在本地仓库或者远程仓库中,让配置中心来负责读取仓库的配置文件,而客户端(服务)从配置中心读取配置。
Spring Cloud Config经常和 Spring Cloud Bus 结合使用,无需重新启动服务即可刷新配置文件(信息)。 - 服务注册和发现
服务治理组件(Eurake、Consul等)相当于交易的信息员,通过它可以发现“服务提供者”,还可以将自己注册到“服务中心”中。 - 路由
通过智能路由网关组件(Zuul、Spring Cloud Gateway)来实现智能路由和请求过滤功能。内部服务接口通过网关统一对外暴露,避免了内部服务敏感信息在未经授权的情况下对外暴露。 - 负载均衡
可以通过Feign(远程调用组件)和Ribbon(负载均衡组件)实现负载均衡。 - 断路器
使用服务容错组件(Hystrix、Resilience4j)控制服务的API接口的熔断,以实现故障转移、服务限流、服务降级等功能,防止微服务系统发生雪崩效应。用Hystrix Dashboard组件监控单个服务的熔断状态,用Hystrix Turbine 组件监控多个服务的熔断的状态。 - 分布式消息传递
通过消息总线组件,数据流操作组件可以将Redis、RabbitMQ、Kafka等封装起来,实现消息的接口和发送。
1.3 服务网格(Service Mesh)框架 Istio
- Istio 简介
Istio将流量管理添加到微服务中,提供了连接、安全、管理和监控微服务的方案。
要让微服务系统支持Istio,只需要在系统中部署一个特殊的Sidecar代理,这样就可以使用Istio控制平台(平面)的功能来配置和管理代理,并拦截微服务之间的所有网络通信。
2.Istio核心功能
- 流量管理
通过其提供的规则配置和流量路由功能,可以很好地控制服务之间的流量和API调用。Istio简化了断路器、超时和重试的配置,并可以轻松设置A/B测试、金丝雀部署、基于百分比的流量分隔部署、分阶段部署等重要任务。 - 安全
Istio提供了认证、授权和加密功能,以实现底层安全通信信道和管理服务通信。 - 监控功能
通过Istio的监控功能,可以了解服务的性能,以及服务如何影响上游和下游的功能。 - 平台网关
Istio 是独立于平台的,它可以在各种环境中运行,包括跨云、K8S(Kubernetes)、Mesos等。
1.4 比较Dubbo、Spring Cloud和Istio
1.4.1 对比架构
- Dubbo 架构图
从图中可以看出,“注册中心”,相当于Spring Cloud 中集成的“服务中心”(Eureka、Consul等),“服务消费者”相当于Spring Cloud中集成的Ribbon。
Dubbo比Spring Cloud 少了很多配套的项目,比如,与重试和失败有关的可靠性和事务性机制。Dubbo专注于RPC领域,未来将成为微服务生态体系中的一个重要组件,而不是成为一个微服务的全面解决方案。 - Spring Cloud 架构图
- Istio 架构图
- Pilot
它为Envoy提供服务发现、流量管理和智能路由,以及错误处理(超时、重试、熔断)功能。用户通过Pilot的API管理网络相关的资源对象。Pilot会根据用户的配置和服务的信息将网络流量管理信息分发到各个Envoy中。 - Mixer
它为整个集群执行访问控制、跨服务网格使用策略(Policy)、管理(Rate Limit、Quota等),并收集从Envoy代理和其他服务自动探测到的数据。Mixer包含一个非常灵活的插件模型;可以与各种主机环境和后端基础架构进行交互,所以它是独立于平台的组件的。 - Citadel
它提供服务之间的认证和证书管理,使服务能够自动升级到TLS协议。 - Sidecar
它在原有的客户端和服务器之间添加了一个代理程序。 - Envoy
它提供服务发现、负载均衡和路由表动态更新API。这些API解耦了Istio和Envoy。代理Proxy(默认使用Envoy)作为Sidecar会和控制中心通信,以获取需要的服务之间的信息,以及汇报服务调用的Metrics(指标)数据。
1.4.2 对比各项数据
Dubbo、Spring Cloud、Istio对比见下表
对比项 | Dubbo | Spring Cloud | Istio |
---|---|---|---|
学习曲线 | 一般 | 平滑,有大量成熟的实例供学习 | 除文档外的资料较少 |
开发效率 | 开发效率低,Jar包依赖和升级问题严重 | 开发效率高,社区支持强大,更新非常快,是一套全方位的解决方案 | 开发效率高。它简化了应用的开发及部署方式,把应用上线所需的外围支撑系统与业务应用相分离,从而减轻开发团队的压力 |
集成性 | Jar包依赖的问题多 | 来源于Spring;质量、稳定性、持续性都可以得到保证;基于Spring Boot,更加便于业务落地 | 目前在Kubernetes上支持比较好 |
文档 | 中英文文档齐全 | 英文文档齐全 | 中英文文档齐全 |
支持的开发语言 | java、node.js、PHP、python、go、Erlang | java、Kotlin、Groovy | 与语言几乎无绑定 |
开源社区活跃度 | 低 | 高 | 高 |
API网关 | 无(网关通过Dubbo提供的负载均衡机制自动完成) | Zuul、Spring Cloud Gateway | Traffic Cotrol 、Egress |
客户端负载均衡 | 无 | Ribbon | Envoy |
批量任务 | 无(可以结合Elastic-Job、Tbschedule) | Spring Batch | 无 |
开源协议 | Apache 2.0 | Apache 2.0 | Apache 2.0 |
1.4.3 总结
Dubbo当年停止更新后,对开发人员的信心有非常大的影响。在2017年重新维护后,其定位为Spring Cloud Alibaba 的RPC组件,运行性能优于Spring Cloud。
Spring Cloud 是Spring家族的产品,一直保持着更新和完善。在企业开发框架中,可以说很难有其他框架能与Spring相提并论。Spring Cloud 的一站式解决方案对于资金和技术实力有限的中小互联网公司来说是极佳选择。Spring Cloud 和Docker等容器的结合也会让Spring Cloud在未来“云”的软件开发中占有一席之地。
Istio作为一个全新的服务网格框架,极好地支持Kubernates(简称K8S,容器编排工具),是一个值得关注的项目。
Dubbo、Spring Cloud、Istio都是有效地实现微服务的工具。企业或个人应根据自身的情况选择合适的架构来解决业务问题。
结合项目背景、提供功能来说,Dubbo稍逊一筹。
Spring Cloud在现阶段或未来较长时间内是最为稳妥的微服务的框架。
如果是技术上采取激进策略的团队则可以考虑采用Istio。