
作者:TIM XU
来源:https://xiaoxubeii.github.io/articles/microservices-architecture-introduction/
微服务初探
什么是微服务
首先微服务并没有一个官方的定义,想要直接描述微服务比较困难,我们可以通过对比传统WEB应用,来理解什么是微服务。
传统的WEB应用核心分为业务逻辑、适配器以及API或通过UI访问的WEB界面。业务逻辑定义业务流程、业务规则以及领域实体。适配器包括数据库访问组件、消息组件以及访问接口等。一个打车软件的架构图如下:

尽管也是遵循模块化开发,但最终它们会打包并部署为单体式应用。例如Java应用程序会被打包成WAR,部署在Tomcat或者Jetty上。
这种单体应用比较适合于小项目,优点是:
开发简单直接,集中式管理
基本不会重复开发
功能都在本地,没有分布式的管理开销和调用开销
当然它的缺点也十分明显,特别对于互联网公司来说:
开发效率低:所有的开发在一个项目改代码,递交代码相互等待,代码冲突不断
代码维护难:代码功能耦合在一起,新人不知道何从下手
部署不灵活:构建时间长,任何小修改必须重新构建整个项目,这个过程往往很长
稳定性不高:一个微不足道的小问题,可以导致整个应用挂掉
扩展性不够:无法满足高并发情况下的业务需求
所以,现在主流的设计一般会采用微服务架构。其思路不是开发一个巨大的单体式应用,而是将应用分解为小的、互相连接的微服务。一个微服务完成某个特定功能,比如乘客管理和下单管理等。每个微服务都有自己的业务逻辑和适配器。一些微服务还会提供API接口给其他微服务和应用客户端使用。
比如,前面描述的系统可被分解为:

每个业务逻辑都被分解为一个微服务,微服务之间通过REST API通信。一些微服务也会向终端用户或客户端开发API接口。但通常情况下,这些客户端并不能直接访问后台微服务,而是通过API Gateway来传递请求。API Gateway一般负责服务路由、负载均衡、缓存、访问控制和鉴权等任务。
微服务架构的优点
微服务架构有很多重要的优点。首先,它解决了复杂性问题。它将单体应用分解为一组服务。虽然功能总量不变,但应用程序已被分解为可管理的模块或服务。这些服务定义了明确的RPC或消息驱动的API边界。微服务架构强化了应用模块化的水平,而这通过单体代码库很难实现。因此,微服务开发的速度要快很多,更容易理解和维护。
其次,这种体系结构使得每个服务都可以由专注于此服务的团队独立开发。只要符合服务API契约,开发人员可以自由选择开发技术。这就意味着开发人员可以采用新技术编写或重构服务,由于服务相对较小,所以这并不会对整体应用造成太大影响。
第三,微服务架构可以使每个微服务独立部署。开发人员无需协调对服务升级或更改的部署。这些更改可以在测试通过后立即部署。所以微服务架构也使得CI/CD成为可能。
最后,微服务架构使得每个服务都可独立扩展。我们只需定义满足服务部署要求的配置、容量、实例数量等约束条件即可。比如我们可以在EC2计算优化实例上部署CPU密集型服务,在EC2内存优化实例上部署内存数据库服务。
微服务架构的缺点和挑战
实际上并不存在silver bullets,微服务架构也会给我们带来新的问题和挑战。其中一个就和它的名字类似,微服务强调了服务大小,但实际上这并没有一个统一的标准。业务逻辑应该按照什么规则划分为微服务,这本身就是一个经验工程。有些开发者主张10-100行代码就应该建立一个微服务。虽然建立小型服务是微服务架构崇尚的,但要记住,微服务是达到目的的手段,而不是目标。微服务的目标是充分分解应用程序,以促进敏捷开发和持续集成部署。
微服务的另一个主要缺点是微服务的分布式特点带来的复杂性。开发人员需要基于RPC或者消息实现微服务之间的调用和通信,而这就使得服务之间的发现、服务调用链的跟踪和质量问题变得的相当棘手。
微服务的另一个挑战是分区的数据库体系和分布式事务。更新多个业务实体的业务交易相当普遍。这些类型的事务在单体应用中实现非常简单,因为单体应用往往只存在一个数据库。但在微服务架构下,不同服务可能拥有不同的数据库。CAP原理的约束,使得我们不得不放弃传统的强一致性,而转而追求最终一致性,这个对开发人员来说是一个挑战。
微服务架构对测试也带来了很大的挑战。传统的单体WEB应用只需测试单一的REST API即可,而对微服务进行测试,需要启动它依赖的所有其他服务。这种复杂性不可低估。
微服务的另一大挑战是跨多个服务的更改。比如在传统单体应用中,若有A、B、C三个服务需要更改,A依赖B,B依赖C。我们只需更改相应的模块,然后一次性部署即可。但是在微服务架构中,我们需要仔细规划和协调每个服务的变更部署。我们需要先更新C,然后更新B,最后更新A。
部署基于微服务的应用也要复杂得多。单体应用可以简单的部署在一组相同的服务器上,然后前端使用负载均衡即可。每个应用都有相同的基础服务地址,例如数据库和消息队列。而微服务由不同的大量服务构成。每种服务可能拥有自己的配置、应用实例数量以及基础服务地址。这里就需要不同的配置、部署、扩展和监控组件。此外,我们还需要服务发现机制,以便服务可以发现与其通信的其他服务的地址。因此,成功部署微服务应用需要开发人员有更好地部署策略和高度自动化的水平。
以上问题和挑战可大体概括为:
API Gateway
服务间调用
服务发现
服务容错
服务部署
数据调用

幸运的是,出现了很多微服务框架,可以解决以上问题。
第一代微服务框架
Spring Cloud
spring cloud config:由git存储库支持的集中式外部配置管理。配置资源直接映射到Spring Environment,但是如果需要可以被非Spring应用程序使用。spring cloud netflix:与各种Netflix OSS组件(Eureka,Hystrix,Zuul,Archaius等)集成。 spring cloud bus:用于将服务和服务实例与分布式消息传递联系起来的事件总线。用于在集群中传播状态更改(例如配置更改事件) spring cloud for cloud foundry:将您的应用程序与Pivotal Cloudfoundry集成。提供服务发现实现,还可以轻松实现通过SSO和OAuth2保护资源,还可以创建Cloudfoundry服务代理。 spring cloud cloud foundry service broker:提供构建管理一个Cloud Foundry中服务的服务代理的起点。 spring cloud cluster:领导选举和通用状态模型(基于zookeeper,redis,hazelcast,Consul的抽象和实现) spring cloud consul:结合Hashicorp Consul的服务发现和配置管理 spring cloud security:在Zuul代理中为负载平衡的OAuth2休眠客户端和认证头中继提供支持。 spring cloud sleuth:适用于Spring Cloud应用程序的分布式跟踪,与Zipkin,HTrace和基于日志(例如ELK)跟踪兼容。 spring cloud data flow:针对现代运行时的可组合微服务应用程序的云本地编排服务。易于使用的DSL,拖放式GUI和REST-API一起简化了基于微服务的数据管道的整体编排。 spring cloud stream:轻量级事件驱动的微服务框架,可快速构建可连接到外部系统的应用程序。使用Apache Kafka或RabbitMQ在Spring Boot应用程序之间发送和接收消息的简单声明式模型。 spring cloud stream app starters:Spring Cloud任务应用程序启动器是Spring Boot应用程序,可能是任何进程,包括不会永远运行的Spring Batch作业,并且它们在有限时间的数据处理之后结束/停止。 spring cloud zookeeper:Zookeeper的服务发现和配置管理 spring cloud for amazon web services:轻松集成托管的Amazon的Web Services服务。它通过使用spring的idioms和APIs便捷集成AWS服务,例如缓存或消息API。开发人员可以围绕托管服务,不必关心基础架构来构建应用。 spring cloud connectors:使PaaS应用程序在各种平台上轻松连接到后端服务,如数据库和消息代理(以前称为“Spring Cloud”的项目) spring cloud starters:作为基于spring boot的启动项目,降低依赖管理(在Angel.SR2后,不在作为独立项目) spring cloud cli:插件支持基于Groovy预言快速创建spring cloud的组件应用
Dubbo
远程通讯: 提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。 集群容错: 提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。 自动发现: 基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。

Dev层的框架,缺少DevOps的整体解决方案(这正是微服务架构需要关注的)。而随之而来的便是Service Mesh的兴起。下一代微服务:Service Mesh?
Service Mesh
应用程序间通讯的中间层 轻量级网络代理 应用程序无感知 解耦应用程序的重试/超时、监控、追踪和服务发现

Linkerd

负载平衡:linkerd提供了多种负载均衡算法,它们使用实时性能指标来分配负载并减少整个应用程序的尾部延迟。 熔断:linkerd包含自动熔断,将停止将流量发送到被认为不健康的实例,从而使他们有机会恢复并避免连锁反应故障。 服务发现:linkerd 与各种服务发现后端集成,通过删除特定的(ad-hoc)服务发现实现来帮助您降低代码的复杂性。 动态请求路由:linkerd 启用动态请求路由和重新路由,允许您使用最少量的配置来设置分段服务(staging service),金丝雀(canaries),蓝绿部署(blue-green deploy),跨DC故障切换和黑暗流量(dark traffic)。 重试次数和截止日期:linkerd可以在某些故障时自动重试请求,并且可以在指定的时间段之后让请求超时。 TLS:linkerd 可以配置为使用 TLS 发送和接收请求,您可以使用它来加密跨主机边界的通信,而不用修改现有的应用程序代码。 HTTP代理集成:linkerd 可以作为 HTTP 代理,几乎所有现代 HTTP 客户端都广泛支持,使其易于集成到现有应用程序中。 透明代理:您可以在主机上使用 iptables 规则,设置通过 linkerd 的透明代理 gRPC:linkerd 支持 HTTP/2 和 TLS,允许它路由 gRPC 请求,支持高级 RPC 机制,如双向流,流程控制和结构化数据负载。 分布式跟踪:linkerd 支持分布式跟踪和度量仪器,可以提供跨越所有服务的统一的可观察性。 仪器仪表: linkerd 支持分布式跟踪和度量仪器,可以提供跨越所有服务的统一的可观察性。
Envoy
对于应用程序而言,网络应该是透明的,当发生网络和应用程序故障时,能够很容易定位出问题的根源。
外置进程架构:可与任何语言开发的应用一起工作;可快速升级 基于新C++11编码:能够提供高效的性能 L3/L4过滤器:核心是一个L3/L4网络代理,能够作为一个可编程过滤器实现不同TCP代理任务,插入到主服务当中。通过编写过滤器来支持各种任务,如原始TCP代理、HTTP代理、TLS客户端证书身份验证等。 HTTP L7过滤器:支持一个额外的HTTP L7过滤层。HTTP过滤器作为一个插件,插入到HTTP链接管理子系统中,从而执行不同的任务,如缓冲,速率限制,路由/转发,嗅探Amazon的DynamoDB等等。 支持HTTP/2:在HTTP模式下,支持HTTP/1.1、HTTP/2,并且支持HTTP/1.1、HTTP/2双向代理。这意味着HTTP/1.1和HTTP/2,在客户机和目标服务器的任何组合都可以桥接 HTTP L7路由:在HTTP模式下运行时,支持根据content type、runtime values等,基于path的路由和重定向。可用于服务的前端/边缘代理 支持gRPC:gRPC是一个来自谷歌的RPC框架,使用HTTP/2作为底层的多路传输。HTTP/2承载的gRPC请求和应答,都可以使用Envoy的路由和LB能力 支持MongoDB L7:支持获取统计和连接记录等信息 支持DynamoDB L7:支持获取统计和连接等信息 服务发现:支持多种服务发现方法,包括异步DNS解析和通过REST请求服务发现服务 健康检查:含有一个健康检查子系统,可以对上游服务集群进行主动的健康检查。也支持被动健康检查。 高级LB:包括自动重试、断路器,全局限速,阻隔请求,异常检测。未来还计划支持请求速率控制 前端代理:可作为前端代理,包括TLS、HTTP/1.1、HTTP/2,以及HTTP L7路由 极好的可观察性:对所有子系统,提供了可靠的统计能力。目前支持statsd以及兼容的统计库。还可以通过管理端口查看统计信息,还支持第三方的分布式跟踪机制 动态配置:提供分层的动态配置API,用户可以使用这些API构建复杂的集中管理部署
Istio
流量管理:控制服务之间的流量和API调用的流向,使得调用更可靠,并使网络在恶劣情况下更加健壮 可观察性:了解服务之间的依赖关系,以及它们之间流量的本质和流向,从而提供快速识别问题的能力 策略执行:将组织策略应用于服务之间的互动,确保访问策略得以执行,资源在消费者之间良好分配。策略的更改是通过配置网格而不是修改应用程序代码 服务身份和安全:为网格中的服务提供可验证身份,并提供保护服务流量的能力,使其可以在不同可信度的网络上流转
数据面板由一组智能代理(Envoy)组成,代理部署为边车,调解和控制微服务之间所有的网络通信 控制面板负责管理和配置代理来路由流量,以及在运行时执行策略

Conduit
对比

Kubernetes + Service Mesh
Dev层面的问题。若想解决Ops问题,它们还需和诸如Cloud Foundry、Mesos、Docker Swarm或Kubernetes这类资源调度框架做结合:
Dev和Ops阶段,结合Service Mesh,它可以为用户提供完整端到端的微服务体验。