由来
微服务概念由
Martin Fowler
(马丁·福勒)2014年3月提出,讨论多年的SOA(Service-Oriented-Architecture,面向服务的架构)有了新的解决方案,恰逢Docker技术的普及,一个崭新的轻量级SOA架构MSA
(Micro Service Architecture,微服务架构)伴随着容器技术正携手前行
原文
马丁·福勒-微服务指南
Chris Richardson-微服务总结
定义
微服务架构
来描述这样一种特定的软件设计方法,即以若干可独立部署的服务方式进行软件应用系统的设计。尽管这种架构风格尚无精确的定义,但其在下述方面还是存在一定的共性,即围绕业务功能的组织、自动化部署、端点智能、和在编程语言和数据方面进行去中心化的控制。
简介
简单来说,微服务架构风格是一种将一个单体应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中,服务间通信采用轻量级通信机制(通常用HTTP资源API)。这些服务围绕业务能力构建并且可通过全自动部署机制独立部署。这些微服务可以使用不同的语言来编写,并且可以使用不同的数据存储技术。对这些微服务我们仅做最低限度的集中管理。
- 单体应用程序
单体应用程序是以一个单个单元的方式来构建的。企业应用系统经常包含三个主要部分:客户端用户界面、数据库和服务端应用系统。
这个服务端的应用系统就是一个单体应用--一个单个可执行的程序。对于该系统的任何改变,都会涉及构建和部署上述服务端应用系统的一个新版本。通过负载均衡运行许多实例,来将这个单体应用进行横向扩展。-
不足
随着应用不断上云,单体应用变更受到了很大的限制,应用系统的一个很小的部分的一处变更,也需要将整个单体应用系统进行重新构建和部署,难以保持一个良好的模块化结构,这使得很难将更改缩小到为需要变更的模块内。当程序进行扩展时,扩展会对整个部分,而不是仅将需要的部分进行扩展。
微服务以构建一组小型服务的方式来构建应用系统。除了服务是可独立部署、可独立扩展的之外,每个服务都提供一个固定的模块边界。甚至允许不同的服务用不同的的语言开发,由不同的团队管理。
-
微服务架构特点
服务组件化
- 何为组件?
组件是可以独立替换和升级的软件单元。 - 好处
如果将应用分解为多个服务,那么对于一个服务的多处修改,仅需要重新部署这一个服务。
这不是绝对的,某些更改会改变服务接口,从而导致某种程度的协调,但是好的微服务架构的目的是通过确定服务边界和服务识别的机制来最小化它们。 - 缺点
远程调用比进程内调用的开销更大,因此远程api需要设计成粗粒度的,这往往更难使用。
如果需要修改组件间的职责分配,这种组件行为的改动会更加难以实现。
围绕“业务功能”组织团队
- 传统开发
当开发一个大型应用系统,往往会在技术层面进行划分如:UI、后端逻辑,数据库等。这样划分仅仅进行一些简单的更改仍然需要大量的时间。
一些团队会对此进行优化,同时采取两害相权取其轻的办法——即强制要求逻辑存在于一切与之相对接的应用程序当中。换言之,也就是实现逻辑的普遍存在性。这正是所谓Conway定律
注
:Conway定律
-
微服务
微服务使用不同的方法来分解系统,即根据业务功能(business capability)来将系统分解为若干服务。这些服务针对该业务领域提供多层次广泛的软件实现,包括用户界面、持久性存储以及任何对外的协作性操作。因此,团队是跨职能的,它拥有软件开发所需的全方位的技能:用户体验、数据库和项目管理。
- 不足
如果这个服务跨越了许多服务的边界,会极大的增加开发难度。而实现组件化的服务所必要的是更加显式的边界,能更加容易地保持团队边界的清晰性。
“做产品”而不是“做项目”
- 传统开发
传统软件开发使用项目模型——即交付软件->完工。一旦完工后,软件就被移交给维护团队,接着那个构建该软件的项目团队就会被解散。 - 微服务
微服务则采用谁构建,谁运行
(you build, you run it)的观点,即一个开发团队对一个在生产环境下运行的软件负全责。
这样的“产品”理念,是与业务功能的联动绑定在一起的。它不会将软件看作是一个待完成的功能集合,而是认为存在这样一个持续的关系,即软件如何能助其客户来持续增进业务功能。
“智能端点”与“傻瓜管道(哑管道)”
- 传统开发
当在不同进程间创建通信结构时,我们可以使用ESB(企业服务总线),其中,ESB产品通常包括用于消息路由,编排,转换和应用业务规则的复杂工具。 - 智能端点
智能端点就是相对ESB中的服务提供者只需要提供一种类型的服务,智能端点需要根据服务调用者的需求提供多种类型的服务以适应业务发展。 - 傻瓜通道
管道只提供路由或者负载均衡之类的,不承载业务逻辑,或者是MQ之类的异步消息中间件,管道根本不关心具体传送的数据,所以与其叫哑管道,不如叫非智能管道 - 微服务
微服务主张采用,智能端点(smart endpoints)和傻瓜管道(dumb pipes)。使用微服务所构建的各个应用的目标,都是尽可能地实现“高内聚和低耦合”——他们拥有自己的领域逻辑,并且更多地是像经典Unix的“过滤器”(filter)那样来工作——即接收一个请求,酌情对其应用业务逻辑,并产生一个响应。这些应用通过使用一些简单的REST风格的协议来进行编制,而不去使用复杂的协议。微服务最常用的两种协议是使用http和轻量级消息传送- http
微服务使用http,微服务团队使用的规则和协议,正是万维网的规则和协议。从开发者和运营人员的角度讲,通常使用的资源可以很容易的缓存。 - 消息队列
第二种常用方法是使用消息队列,选择的基础设施是典型的傻瓜的(只充当消息路由器) - 像RabbitMQ
或ZeroMQ
这样简单的实现仅仅提供一个可靠的异步交换结构 - 在服务里,智能仍旧存活于端点中,生产和消费消息。
- http
"去中心化"治理
- 中心化不足
中心化的后果是趋向于在技术平台上制定标准,事实证明这种方式是有局限性的 - 微服务
将单块应用的那些组件拆分成多个服务,那么在构建每个服务时,就可以有选择不同技术栈的机会。比如node、C++、或者不同的数据库
去中心化治理的最高境界就是亚马逊的build it/run it
理念。
即团队对他们所构建的软件负全责
"去中心化"数据管理
- 微服务
微服务更喜欢让每一个服务来管理其自有数据库。其实现可以采用相同数据库技术的不同数据库实例,也可以采用完全不同的数据库系统。这种方法被称作“混合持久化”(Polyglot Persistence)。
对跨微服务的数据来说,去中心化责任对管理升级有影响。处理更新的常用方法是在更新多个资源时使用事务来保证一致性。这个方法通常用在单应用中。
使用事务会保证业务的一致性,但是会严重提高服务之间的耦合性,这在横跨多个服务时是有问题的。
分布式事务是出了名的难以实现,因此微服务架构强调服务间的无事务协作,即对一致性可能只是最后一致性和通过补偿操作处理问题。
基础设施自动化
基础设施自动化技术在过去几年里已经得到长足的发展,使用微服务构建的产品和系统的团队,都具备极其丰富的CD和CI的经验。用这种方法构建软件的各个团队,广泛采用了基础设施的自动化技术。
使用微服务的团队更加依赖于基础设施的自动化。相比之下,在整体架构也微服务架构中,尽管发布的场景不同,但发布工作的无趣并没有多大的区别。
“容错”设计
服务可以在任何时候发生故障,所以下面两件事就变得很重要,即能够快速地检测出故障,而且在可能的情况下能够自动恢复服务。
各个微服务的应用都将大量的精力放到了应用程序的实时监控上,来检查“架构元素指标”(例如数据库每秒收到多少请求)和“业务相关指标”(例如系统每分钟收到多少订单)。
当系统某个地方出现问题,语义监控系统能提供一个预警,来触发开发团队进行后续的跟进和调查工作。
微服务团队希望在每一个单独的服务中,都能看到先进的监控和日志记录装置。例如显示“运行/宕机”状态的仪表盘,和各种运维和业务相关的指标。另外我们经常在工作中会碰到这样一些细节,即熔断器的状态、当前的吞吐率和延迟,以及其他一些例子。
“演进式”设计
当你试图把软件系统组件化时,就面临着如何进行划分的决策 —— 我们决定分割我们的应用的原则是什么?组件的关键特性是具有可独立的更换和升级的特点 —— 这意味着,可以重写该组件,而无须影响该组件的其他合作组件。事实上,许多微服务的团队会明确地预期许多服务将来会报废,而不是守着这些服务做长期演进。
这种强调可更换性的特点,是模块化设计一般性原则的一个特例,通过“变化模式”(pattern of change)来驱动进行模块化的实现。将那些能在同时发生变化的东西,放到同一个模块中。系统中那些很少发生变化的部分,应该被放到不同的服务中,以区别于那些当前正在经历大量变动(churn)的部分。如果发现需要同时反复变更两个服务时,这就是它们两个需要被合并的一个信号。