微服务概念解析(上)

探讨这一全新架构术语的确切定义

“微服务架构”概念的提出已经有很长一段时间了,但在最近几年却开始频繁地出现。微服务架构是一种特定的软件应用程序设计方式——将大型软件拆分为多个独立可部署服务组合而成的套件方案。虽然这种架构风格的确切定义还存在争议,但并不妨碍其在众多企业的实际应用中被实践,并体现出了具有通用特征的业务功能、自动化部署、端点智能化以及对语言与数据的离散化控制能力。数据库

Docker 做为一种开源的应用容器引擎,帮助开发者将他们的应用以及依赖打包到一个可移植的容器中,便于应用的部署和扩展。而随之产生的微容器概念和微服务正好相辅相成,经过 Docker 封装的应用能够轻松运行在以扩容能力见长的云计算平台上。数人云做为专业的数据中心管理系统,提供了基于 Mesos 和 Docker 技术的企业级容器云生产环境,经过一键部署、横向扩展、持续集成等特性,助力微服务架构在企业应用环境的实践。编程

因为篇幅问题,本文将分上下两篇,下篇将于明天放送给你们。后端

“微服务”——目前可谓早已人满为患的软件架构领域的新兴名词。虽然咱们对于这种新生事物每每带着一种先入为主的蔑视与忽略态度,但通过几年的历练,咱们发现这种软件构建风格正变得愈来愈具备吸引力。过去几年中已经有诸多企业将其引入实际项目,而至今其结果仍然至关积极,这甚至促使不少同业人士开始将微服务架构做为企业级应用程序的默认开发途径。但遗憾的是,目前仍然缺少一套系统的概念定义,告诉咱们微服务究竟是如何实现这些成效的。数组

简而言之,微服务架构风格[1]是一类将单一应用程序做为由众多小型服务构成之套件加以开发的方式,其中各项服务都拥有本身的进程并利用轻量化机制(一般为HTTP源API)实现通讯。这些服务围绕业务功能创建而成,且凭借自动化部署机制实现独立部署。这些服务匹配一套最低限度的中央式管理机制,且各服务可经过不一样编程语言编写而成并使用不一样的数据存储技术。
图片描述
要解释微服务风格,那么首先应当将其与总体风格进行比较:总体应用程序做为单一单元进行构建。企业级应用程序一般包含三个组成部分:一套客户端用户界面(由运行在用户设备上的浏览器中的HTML页面以及JavaScript代码构成)、一套后端数据库(将大量插入至数据库管理系统的大量表构成,一般采用关系数据库)以及一款服务器端应用程序。该服务器端应用程序将负责处理HTTP请求、执行域逻辑、对来自数据库的数据进行检索与更新,同时选定HTML视图并将其发送至浏览器端。此服务器端应用程序一般为单一的逻辑可执行文件[2]。任何针对该系统的变动都须要对该服务器端应用程序进行新版本构建与部署。浏览器

这样的总体服务器机制在构建此类系统中可谓不可或缺。咱们用于处理请求的所有逻辑都运行在单一进程当中,容许你们使用语言中的基本功能以将该应用程序拆分为类、函数以及命名空间。经过这种方式,咱们可以在开发人员的笔记本设备上运行并测试应用程序,同时利用一整套部署流程以确保所有变动都通过妥善测试然后被部署在生产环境当中。你们能够将大量实例运行在一套负载均衡方案以后,从而实现横向扩展能力。缓存

这类总体应用程序固然可以切实起效,但人们却逐渐发现其中存在着诸多弊端——特别是在将大量应用程序部署在云环境当中的状况下。因为变动周期被大量集中于一处——即便仅仅指向应用程序中的一小部分,单一变动亦要求咱们对应用程序总体进行重构与从新部署。随着时间推移,咱们每每很难保证理想的模块化结构,这意味着本应只影响单一模块的变动每每会扩散至该模块以外。规模伸缩亦要求咱们对总体应用程序进行规模调整,而非单纯为其中必要的部分进行资源扩容。服务器

图片描述
图一:总体型应用程序与微服务架构应用程序架构

正是这些弊端造就了现在的微服务架构风格:即以服务套件的形式构建应用程序。除了各服务可以单独进行部署与规模伸缩以外,每项服务还具有牢固的模块边界,甚至容许咱们在不一样的服务当中使用不一样的编程语言进行代码编写。另外,各服务亦可由不一样团队负责管理。负载均衡

咱们认为微服务风格并不算什么新鲜事物或者创新成果,其历史至少能够追溯至Unix设计时代。但咱们同时亦坚信,微服务架构一直未能受到足够的重视,而其确实可以帮助你们更好地完成软件开发工做。运维

微服务架构之特性

咱们没法给微服务架构风格出具一条确切的定义,但咱们却能够根据该架构表现出的各种共同特性对其加以描述。正如各种根据共同特性作出的定义同样,并非全部微服务架构都符合这些特性,但能够确定的是具有这些特性的微服务架构占据大部分比例。尽管咱们各部份内容的做者仅仅是相关技术社区中的活跃成员,但制做这份文档是为了对采用微服务架构的工做流程及成果作出总结,并且其中仍有至关一部分表述并不是严格定义——只应做为常见状况考量。

经过服务实现组件化

长久以来,咱们一直参与软件行业以内并意识到人们对利用组件整合方式构建系统的渴望——这种思路与咱们在物理世界中采起的构建机制很是类似。而在过去几十年当中,咱们发现已经有大量公共库渗透到多数语言平台当中并成为其坚实的组成部分。

在谈到咱们所使用的组件时,你们可能会发现不一样群体对组件的定义也有所区别。咱们对组件作出的定义是,其属于软件中的一类单元,且具有可更替性与可升级性。

微服务架构会使用这些库,但其实现组件化的主要手段则是将软件拆分红多个服务。咱们将“库”定义为与程序相对接且可经过内存内函数调用发挥做用的组件,而“服务”则为进程以外的组件,其可经过Web服务请求或者远程程序调用等方式实现通讯。(这里的服务概念与多数OO程序中的服务对象概念有所区别[3])。

将服务做为组件加以使用(而非库)的一大缘由在于,服务具有独立可部署能力。若是你们的应用程序[4]由单一进程中的多个库构成,那么指向任何单一组件的变动都会导致该应用程序必须进行从新部署。但若是该应用程序被拆分红多项服务,那么单一服务变动将只会导致该服务进行从新部署。虽然这并不是绝对,例如某些变动会致使服务接口受到影响,但一套优秀的微服务架构旨在尽量少地对服务协议中的服务边界及演进机制产生干扰。

将服务做为组件的另外一个理由在于实现更为明确的组件接口。大多数编程语言并不具有用于定义明确发布接口的良好机制。通常来说,其只会提供说明文档及规则以防止用户打破组件封装,但这同时亦会致使不一样组件之间的耦合程度太高。利用明确的远程调用机制,服务可以轻松避免此类难题。

但以这种方式使用服务亦存在必定弊端。远程调用在资源需求方面每每远高于进程内调用,所以远程API须要采起粗粒度设计,但这亦会增长API的使用难度。若是你们须要更改不一样组件间的职能分配,那么这类需求在跨越进程边界时每每不易实现。

经过粗略观察,咱们每每会发现这些服务会与各运行时进程相映射——但这仅仅只是第一印象。一项服务可能由多个进程构成,且各进程始终共同进行开发与部署——这方面实例包括只由单一服务所使用的应用程序进程以及数据库。

围绕业务功能构建组织

当着眼于将单一大型应用程序拆分红多个组成部分时,管理人员一般更重视技术层,其中具体包括UI团队、服务器端逻辑团队以及数据库团队。当这些团队据此进行拆分时,即便是最简单的变动也将给项目形成跨团队协做负担,并所以致使时间与预算的双重支出。睿智的团队会对此进行优化,同时采起两害相权取其轻的办法——即强制要求逻辑存在于一切与之相对接的应用程序当中。换言之,也就是实现逻辑的广泛存在性。这正是所谓康威法则[5]的一种实际表现形式。

任何组织在设计一套系统(广义层面的系统)时,其设计成果都会直接体现该组织所使用的沟通结构。
--梅尔文·康威,1967年
图片描述

图二:康威定律的实际体现

微服务方案对于各部门而言是一种不一样于以往,且以业务功能为核心的服务拆分及组织途径。此类服务采用软件方案在业务层面中的普遍实现堆栈,具体包括用户界面、持久性存储以及任何外部协做机制。所以,各团队将拥有跨职能特性,包括开发过程中要求的所有技能组合:用户体验、数据库以及项目管理等等。

图片描述
图三:由团队边界决定的服务边界

微服务架构有多“微”?

尽管“微服务”早已成为一种极具人气的架构类型,但这一名称却并不能准确反映服务的实际规模——换言之,“微”服务并不必定微。在与众多微服务从业者的交流当中,咱们发现服务的具体规模可谓多种多样。其中规模最大的成果源自Amazon公司旗下的“两块披萨”团队(即整个团队只需两块披萨便可填饱肚子),这意味着其总人数在十位左右。而规模较小的团队则由六人组成,负责支持六项服务。

那么这就带来了新的问题:这种十二人对单项服务的机制同一人对单项服务之间存在着怎样的差异?两者也许不可一律而论。就目前而言,咱们姑且认为双方属于同类团队结构,但随着对微服务认识的持续深刻,也许咱们将来将抱持新的观点。

采起此类组织方式的企业实例可参见www.comparethemarket.com,其各职能团队共同负责构建并运营每款产品,而每款产品则被拆分为一系列独立的服务——且各服务间经过一套消息收发总线实现通讯。

大型总体应用程序亦能够始终围绕业务功能实际模块化,不过这种情况并不常见。诚然,咱们都据说过由大型团队构建的单一总体应用程序根据自身业务线进行设计与划分。然而在这类状况下,最大的问题在于总体应用程序在组织当中须要考虑太多背景信息。若是其总体范畴当中包含太多模块边界,那么团队中的单一成员将很难经过短时间记忆对其进行管理。除此以外,咱们发现这种模块化业务线的维护工做还要求相关人员具有极高的专业技能水平。相比之下,服务组件可以令拆分方式更为明确,从而大大简化团队边界的设定与认知。

产品而非项目

大部分应用程序开发工做都会遵循项目模式:其目标在于交付软件方案中的特定部分,并拥有直观的完成指标。在软件开发工做完成后,其会被传递至运维部门,这时负责构建该软件的团队也将即刻解散。

微服务的支持者们则认为这种模式并不可取——他们的主张是相关团队应该伴随产品走过整个生命周期。这方面最典型的例子应该是Amazon公司提出的“谁构建,谁运行”原则,其中开发团队须要对生产环境下的软件成果承担所有责任。这就要求开发人员在平常工做中全程关注其软件的生产运行状况,同时掌握来自用户的反馈意见,意味着他们须要在必定程度上为用户提供技术支持服务。

产品的定位应始终与业务功能相协调。相较于以往将软件视为一整套已经完成的功能集的心态,微服务架构要求咱们全程与之保持关联,并思考该软件可以如何协助用户增强业务功能。

固然,咱们彻底能够将一样的思路引入总体应用程序当中,不过大量小型服务集合可以显著简化服务开发人员与及用户之间的我的联系。

智能化端点与傻瓜式流程

在跨越不一样进程构建通讯结构时,咱们发现不少产品及方案会直接把智能化机制塞进通讯机制本体当中。这方面的典型实例就是企业服务总线(简称ESB),ESB产品当中一般包含复杂度极高的消息跌幅、编排、转换以及业务规则应用等机制。

微服务社区则倾向于使用另外一种实现方式:智能化端点与傻瓜式流程。采用微服务架构的应用程序旨在尽量实现解耦化与关联性——它们各自拥有本身的域逻辑,并且在经典Unix场景下的运做方式更像是过滤器机制——接收请求、应用合适的逻辑并生成响应。这一切都经过简单的REST类协议实现编排,而非经由WS-Choreography或者BPEL等复杂协议以及中央编排工具实现。

目前最经常使用的两类协议为配合源API的HTTP请求-响应与轻量化消息收发协议[6]。对于前者,最简练而准确的说明是:

立足于Web,而非居于Web背后。
-- Ian Robinson**

微服务团队采用的正是万维网(在很大程度上亦包括Unix在内)所遵循的原则与协议。通常来说,其使用的资源可以为开发人员或者运维人员轻松实现缓存处理。

第二类做法则是立足于轻量化消息总线实现消息收发。这类基础设施选项一般具有傻瓜式特性(这种傻瓜特性体如今实现操做上,即只需匹配消息路由机制,再无其它)——以RabbitMQ或者ZeroMQ为表明的简单实现方案仅仅须要提供一套可靠的异步结构,而服务的所有智能化元素仍然存在于端点当中并负责消息的生成与消费。

在总体应用程序当中,各组件在进程内执行并经过方法调用或者函数调用的方式实现彼此通讯。将总体应用程序转化为微服务形式的最大难题在于改变这种通讯模式。由内存内方法调用指向PC通讯机制的简单转换每每没法良好起效。相反,你们须要利用粗粒度方式取代本来的细粒度通讯机制。

脚注

1: “微服务”一词最先被威尼斯附近的一个软件架构师小组于2011年5月首次说起,当时他们用这个词汇来描述本身近期研究项目当中所涉及的通用性架构机制。2012年5月,该小组做出最终决议,认为“微服务”是最适合的架构名称。2012年3月,James在《微服务-Java以及Unix方式》当中就此发表了一篇案例研究报告,而Fred George也几乎在同一时间进行了相同的工做。Netflix公司的Adrian Cockcroft将微服务架构称为“细化SOA”,并认为这是一套在Web规模下具有开创意义的架构类型。Joe Walnes、Dan North、Evan Botcher以及Graham Tackley也分别在这篇文章中对此做出了评论。

2: 文章中所使用的“总体”一词长久以来一直被Unix业界所使用。其首次出如今《Unix编程艺术》一书中,用于描述那些过于庞大的系统方案。

3: 不少面向对象设计人员,也包括咱们本身,都会在域驱动设计当中使用“服务对象”这一表述,专指那些并不具有实质性联系但却拥有重要做用的对象。这与咱们在本文中所使用的“服务”一词在表意上彻底不一样。遗憾的是,服务这个词汇同时具有两种含义,而咱们对这种多义词也没有更好的处理办法。

4: 咱们将一款应用程序视为一套社会性体系,其中融合了代码库、函数组以及供应主体。

5: 你们能够查看梅尔文 康韦网站上的原文论述。

6: 对于规模极为庞大的应用体系,企业一般会采用二进制协议——例如protobufs。使用二进制协议的系统仍然符合智能化端点与傻瓜式通道的特性——并为了规模化而在透明度方面做出妥协。不过大多数Web方案与绝大多数企业不须要在这方面考虑太多——通常来说,透明度越高、效果就越好。

相关文章
相关标签/搜索