微服务架构简析

微服务是什么?

谈及微服务架构,2016年应该是软件业微服务爆发的元年,微服务到底是什么?
观察现有的软件业,使用单独一款开发语言区开发一款较为全面的产品很少,大多数都是各种语言编写的功能模块进行组装成完整的业务模型,
各语言效率优势互补。
微服务架构所强调的特点就是业务系统需要彻底的组件化与模块分割,原有的单个业务系统分割成多个小应用,每个小应用可以进行独立开发,管理,运行和测试,甚至连每个产品的前端(UI加结构),服务端(控制层,逻辑层和持久化层),数据库都是完全独立的产品,通过微服务架构将每个小应用进行整合,交互与集成,每个小应用不仅能够自己完全独立的功能,还可以运行其他小应用的服务,同时也将自己作为可供利用的服务对象。

采用一组服务的方式来构建一个应用,服务独立部署在不同的进程中,不同服务通过一些轻量级交互机制来通信,例如 RPC、HTTP 等,服务可独立扩展伸缩,每个服务定义了明确的边界,不同的服务甚至可以采用不同的编程语言来实现,由独立的团队来维护。简单的来说,一个系统的不同模块转变成不同的服务!而且服务可以使用不同的技术加以实现。

有了微服务,彻底的将耦合性再次的降低,彼此之间可以高效解耦。

关于微服务到底是个啥,我这里引用了一个知乎的回答,很有意思:
作者:dz902
链接:https://www.zhihu.com/question/37808426/answer/195479692
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

很久以前的一天,Martin 在跟好友的交流中悟到了一种很棒的架构设计。他总结了一下,然后告诉了好友,好友说,这不是新鲜东西,早有人总结了,叫做 SOA。Martin 很高兴,开始在公司内外推广 SOA。结果,不停有人质疑和挑战他。

你这不是 SOA 吧?SOA 这里应该是如此这般的。对,这里我对 SOA 的理解是这样的。你看,这本 SOA 的书说的和你说的有出入。粒度?SOA 没有谈到这个呀,你这不是 SOA。分层跟 SOA 没有关系,你为什么要说这个呢?

…Martin 没办法,心一横,老子就叫它 Martin’s SOA。老子发明的词,老子就是最高权威,有最终解释权。还有谁不服?同事们一看,这思想本身很不错,值得推广,但叫 Martin’s SOA 太没品了吧?还是要取个好一点的名字,最好还能跟 SOA 有某种暗示传承。干脆就叫 Microservices 好了,又新,又有服务含在其中。

Martin 忿忿地接受了这个建议,心里想着:妈的,明明就是 SOA,一群傻逼非要逼我取个新名字。后来 Martin 发现每次提一个东西就会收到旧恶傻势力对解释权的挑战,所以每次要提一个什么概念,都去发明一个新词,免得一群人在那一边质疑挑战,一边大谈“我的理解”。

这就是微服务、敏捷、精益企业、持续集成、持续交付背后的故事。一个名词产生之后,命名者的解释权就会随着时间而弱化(比如 Cooper 发明的 Persona 就被无数设计师乱用)。
敏捷已经有点烂了,等微服务也烂了,我们还会发明新词。实在没辙,都是被逼的啊。

微服务有以下几个特征:

  1. 通过服务实现组件化;
  2. 按业务能力来划分服务与组织团队;
  3. 服务即产品;
  4. 智能终端与哑管道;
  5. 去中心统一化;
  6. 基础设施自动化;
  7. Design for failure;
  8. 进化设计

上面讲到微服务与SOA的宫斗戏码,又来讲讲什么是SOA?

SOA架构

SOA是什么?SOA全英文是Service-Oriented Architecture,中文意思是中文面向服务编程,是一种思想,一种方法论,一种分布式的服务架构

可以肯定的是SOA和微服务的确是一脉相承的,大神Martin Fowler提出来这一概念可以说把SOA的理念继续升华,精进了一步。其核心思想是在应用开发领域,使用一系列微小服务来实现单个应用的方式途径,或者说微服务的目的是有效的拆分应用,实现敏捷开发和部署 ,可以是使用不同的编程语言编写。而SOA可能包含的意义更泛一些,更不准确一些。

用途:SOA解决多服务凌乱问题,SOA架构解决数据服务的复杂程度,同时SOA又有一个名字,叫做服务治理。

架构由中心式转为分布式的演变过程

这里给一个电商服务由传统架构改向分布式架构的流程图

logo

当我们的项目比较小时,我们只有一个系统,并且把他们写到一起,放在一个服务器上,但是随着平台越来越大,数据量越来越大,我们不得不通过分库,把多个模块的数据库分别放在对应得服务器上,每个模块调用自己的子系统即可。

logo

随着我们系统的进一步复杂度的提示,我们不得不进一步对系统的性能进行提升,我们将多个模块分成多个子系统,多个子系统直接互相调用(因为SOA一般用于大型项目,比较复杂,所以一般总系统不会再集成,会拆分多个,分别做成服务,相互调用)。当我们的电商UI进行一个下订单的任务时,多个服务直接互相调用,系统通过数据总线,分别调用对应的子系统即可。

企业数据总线(ESB):企业数据总线不是对多个子模块的集成,他在这里充当数据通道的作用,数据总线不关心业务,数据总线根据给的地址和协议去调服务,上端不关心服务在哪里是什么,只找数据总线。

上面几个图应该算是比较清楚了,随着业务的深入,我们不得不对系统进行调整,分别是对数据和业务的拆分,最后每个子系统对面提供服务。

还要提的一点就是下面那个图,下面的IP库以及几个子系统是公共服务,分别向上提供功能,也是SOA方法论的一部分。

logo

通过上面的图我们可以看出,多个子系统直接相互交互,相互调用非常凌乱,这样我们就很不爽,所以我们就用到了我们的SOA架构,SOA又叫服务治理,SOA就是帮助我们把服务之间调用的乱七八糟的关系给治理起来,然后提供一个统一的标准,把我们的服务治理成下图所示,以前我们的服务是互相交互,现在是只对数据总线进行交互,这样系统就变得统一起来。

logo

统一标准:各系统的协议、地址、交互方式。

新的交互方式:各个系统分别根据统一标准向数据总线进行注册,各子系统调用其他子系统时,我们并不关心如果找到其他子系统,我们只找数据总线,数据总线再根据统一标准找其他子系统,所以数据总线在这里充当一个只路人的作用。

首先Martin Fowler提出SOA歧义Service Oriented Ambiguity,认为”什么是SOA”是不可能回答,因为不同的人意味着不同的事情,SOA意味服务接口,意味流程整合,意味资源再利用,意味着管制,在下面SOA组件图中,服务和服务消费者(客户端)之间存在多个约束,当一个服务显式暴露后,客户端能够通过绑定定位到该服务,相当于两者签订了合同,规定了合同内容和如何实施,具体合同的描述是通过消息方式进行

logo

由于Java等传统语言主要是以类表达对象,将功能行为封装在类内部,而业务客户一般都是注重软件的功能,包括同行业公司系统之间数据交流也是以功能服务为接口,因此,面向服务的架构SOA更加贴近业务客户,也更适合业务伙伴之间流程整合,各个行业已经诞生自己行业特点的SOA,例如电信联盟的NGOSS,已经成为电信行业业务支撑系统BOSS的标准。SOA不但是技术用语,也是业务销售用语,通过服务这个中间概念,可以实现业务和技术之间的无缝转换,如今SOA已经和REST DDD以及云计算等新技术方法结合。其内部主要概念有SCA ESB JBI等等,涉及工作流 规则引擎 消息总线等多个技术细节方面。

通常,一个架构师进行系统架构顶层设计时,必须考虑使用者的利益,不能单单实现软件的功能,还要考虑到软件的性能Scalable 可用性available/usable 安全性等软件质量,还要借鉴社区的最佳实践和经验形成的模式和反模式,避免重蹈覆辙和陷阱,再大胆采取最新的软件技术(比如用REST替代SOAP等)。

服务的提出其实隐含了两个概念,服务提供者和服务消费者,这两者之间有一个合同约定,这非常类似我们现实生活中签订的服务合同,A单位和B单位分别是服务的提供者和消费者,两者签订了一个服务合同,规定A为B提供某项服务。服务就是提供一些公共需求的设施,通过一个工作过程能提供帮助,使用,让使用者受益。

服务具体有如下:Windows Service:如PC定位者RPC Locator, 事件日志EventLog, DHCP Client,;. 软件服务Software Service,如分布式服务Distribution Service, 警告服务Alert Service 安全服务 Security Service, 日志服务;业务服务Business Service,如 帐号和客户服务,销售服务,订单服务,采购服务。

服务两个重要特点:自治和管制,自治代表服务不能被外部势力牵制,比如如果一个服务内部处理中需要调用外部资源或等待外部流程结束,这种等待不能影响服务本身的调用,如果一个服务分为显式对外和隐式内部两个部分,那么自治是针对隐式内部,意味着我们不能在具体一个服务中直接使用同步代码实现复杂功能。如:

public AServiceImpl implements AService{

  public void productSale(...){

    Product product = productService.getProduct();
    int inventory = InventoryService.getInventory(product);
    int price = priceService.getPrice(product);


  }

}

在AServiceImpl的productSale方法中,我们获得商品的库存和定价,都是通过同步的RPC实现调用的,这样造成productSale方法依赖于InventoryService和priceService,无法实现自身自治。

实现服务真正自治,实际就是解决类之间依赖耦合的问题,消息是一种方式,但是基于消息又有两种通讯方式,基于请求响应和基于事件的EDA。

从服务自治可以看出,为什么要提出服务必须自治,因为服务是受管制的,在实际业务活动中,不同服务是被不同部分管理,比如定价服务归属财务部门系统,库存归属仓库系统,涉及系统之间调用协调不能自己使用同步RPC,而是需要消息。

在实际应用中,很多单位使用SOA主要看中其能够无缝整合新旧系统,称为EAI企业应用整合,下图是苏宁的一种SOA图,使用ESB企业服务总线这样的消息系统整合了新旧各种系统。

logo

ESB

ESB全称为Enterprise Service Bus,即企业服务总线。它是传统中间件技术与XML、Web服务等技术结合的产物。ESB提供了网络中最基本的连接中枢,是构筑企业神经系统的必要元素。ESB的出现改变了传统的软件架构,可以提供比传统中间件产品更为廉价的解决方案,同时它还可以消除不同应用之间的技术差异,让不同的应用服务器协调运作,实现了不同服务之间的通信与整合。从功能上看,ESB提供了事件驱动和文档导向的处理模式,以及分布式的运行管理机制,它支持基于内容的路由和过滤,具备了复杂数据的传输能力,并可以提供一系列的标准接口。

logo

数据总线是起到调度服务的作用,数据总线不是集成服务,数据总线更新一个调度框架,每个服务需要根据约定向数据总线注册服务,那么如何注册那?其实数据总线就像一个字典结构,

数据总线里面一个key对于一个value,key指的是服务名,value则是服务的调度方式,还有一点需要说明的是,数据总线只是指路人,服务是不经过数据总线的,如上图的黄色线的路径。

企业服务总线(EnterpriseServiceBus,ESB)从面向服务体系架构(Service-OrientedArchitecture,SOA)发展而来,是传统中间件技术与XML、Web服务等技术结合的产物。
ESB提供了网络中最基本的连接中枢,是构筑企业神经系统的必要元素。ESB采用了“总线”这样一种模式来管理和简化应用之间的集成拓扑结构,以广为接受的开放标准为基础来支持应用之间在消息、事件和服务级别上动态的互连互通,是一种在松散耦合的服务和应用之间标准的集成方式。它可以作用于:
①面向服务的架构—分布式的应用由可重用的服务组成;
②面向消息的架构—应用之间通过ESB发送和接受消息;
③事件驱动的架构—应用之间异步地产生和接收消息。
ESB的出现改变了传统的软件架构,可以提供比传统中间件产品更为低廉的解决方案,同时它还可以消除不同应用之间的技术差异,让不同的应用服务器协调运作,实现了不同服务之间的通信与整合。从功能上看,ESB提供了事件驱动和文档导向的处理模式,以及分布式的运行管理机制,它支持基于内容的路由和过滤,具备了复杂数据的传输能力,并可以提供一系列的标准接口。

ESB 是传统中间件技术与XML、Web服务等技术相互结合的产物,ESB的出现改变了传统的软件架构,可以提供比传统中间件产品更为廉价的解决方案,同时它还可以消除不同应用之间的技术差异,让不同的应用服务器协调运作,实现了不同服务之间的通信与整合。从功能上看,ESB提供了事件驱动和文档导向的处理模式,以及分布式的运行管理机制,它支持基于内容的路由和过滤,具备了复杂数据的传输能力,并可以提供一系列的标准接口。

大规模分布式的企业应用需要相对简单而实用的中间件技术来简化和统一越来越复杂、繁琐的企业级信息系统平台。面向服务体系架构(SOA)是能够将应用程序的不同功能单元通过服务之间定义良好的接口和契约联系起来。SOA使用户可以不受限制地重复使用软件、把各种资源互连起来,只要IT人员选用标准接口包装旧的应用程序、把新的应用程序构建成服务,那么其他应用系统就可以很方便的使用这些功能服务。
支撑SOA的关键是其消息传递架构-企业服务总线(ESB)。ESB是传统中间件技术与XML、Web服务等技术相互结合的产物,用于实现企业应用不同消息和信息的准确、高效和安全传递。让不同的应用服务协调运作,实现不同服务之间的通信与整合。ESB在不同领域具有非常广泛的用途:

电信领域:ESB能够在全方位支持电信行业OSS的应用整合概念。是理想的电信级应用软件承载平台。
电力领域:ESB能够在全方位支持电力行业EMS的数据整合概念,是理想的SCADA系统数据交换平台。
金融领域:ESB能够在全方位支持银企间业务处理平台的流程整合概念,是理想的B2B交易支撑平台。
电子政务:ESB能够在全方位支持电子政务应用软件业务基础平台、信息共享交换平台、决策分析支撑平台和政务门户的平台化实现。

使用SOA和ESB能够灵活实现业务流程管理,工作流的管理BPM,如下图,一个订单的产生可能需要几个部门批准才能完成,而且这几个部门经常是变化的,如何灵活实现这种批准流程的定制也成为SOA实现的一部分,如下:

logo

注意图中1 2 3 4 5 6 7 8 9标注的订单处理流程步骤,这种不同服务之间调用处理顺序可通过BPM进行灵活定制。

目前提供SOA全套解决方案和产品的厂商很多,包括IBM SAP和Oracle,国内金蝶用友浪潮软件等等,比如苏宁的SOA是以SAP为主的八国联军组装,既然SOA中间件服务商已经为我们提供了成熟的架构方案和产品,那么作为SOA使用者是否就无需顶层架构设计了呢?当然不是,SOA使用者要根据自己业务进行模块划分,进行领域建模设计,根据DDD领域驱动设计将业务分解为一个上下文模块,然后再用服务作为对外接口,内部封装的是DDD聚合根,而传统SOA作法是内部封装的是数据表的DTO,从而导致SOA服务内部腐烂堵塞,违背SOA自治和可用性等原则约束。具体可见DDD领域驱动设计。

SOA的好处
1.松耦合:由于服务自治,有一定封装边界,服务调用交互是通过发布接口。这意味着应用程序不感兴趣的服务如何被实现。
2.位置透明:服务的消费者不必关系服务位于什么地方。
3.可在异构平台间复用。可以将遗留系统包装成服务。
4.便于测试,能并行开发,较高可靠性和良好可伸缩性。
5.降低用户成本,用户不需要关心各服务之间是什么语言的、不需要知道如果调用他们,只要通过统一标准找数据总线就可以了。
6.程序之间关系服务简单
7.识别哪些程序有问题(挂掉)

缺点:提示了系统的复杂程度,性能有相应影响。

从实现方式上,两者都是中立性,语言无关,协议跨平台,相比SOA,微服务框架将能够带来更大的敏捷性,并为你构建应用提供更轻量级、更高效率的开发。而SOA更适合大型企业中的业务过程编排、应用集成。

另外还有微服务甚至是去ESB、去中心化、分布式的,而SOA还是以ESB为核心,大量的WS标准实现。再次,从服务粒度上,既然是微,必然微服务更倡导服务的细粒度,重用组合,甚至是每个操作(或方法)都是独立开发的服务,足够小到不能再进行拆分。而SOA没有这么极致的要求,只需要接口契约的规范化,内部实现可以更粗粒度,微服务更多为了可扩充性、负载均衡以及提高吞吐量而去分解应用,但同时也引发了打破数据模型以及维护一致性的问题。

微服务相比于SOA粒度更细。

最后,从部署方式上,这个是最大的不同,对比Monolithic(有人翻译为单体)的Java EE部署架构,通过展现层打包WARs,业务层划分到JARs最后部署为EAR一个大包,而微服务则打开了这个黑盒子,把应用拆分成为一个一个的单个服务,应用Docker技术,不依赖任何服务器和数据模型,是一个 全栈应用,可以通过自动化方式独立部署,每个服务运行在自己的进程中,通过轻量的通讯机制联系,经常是基于HTTP资源API,这些服务基于业务能力构建,能实现集中化管理(因为服务太多啦,不集中管理就无法DevOps啦)。

引用知乎比喻:

以一个公司为例:有基层员工 有管理层 有老板,最初大家都听老板指挥,谁干什么谁干什么,根据需要,你可能今天干A事情,明天干B事情,后来人越来越多了,事情也越来越多了,做事情的效率越来越多,管理也很混乱,就开始做部门划分(服务化),专门部门做专门事情的,IT部门只做研发,人事部门只做招聘; 这个时候就无法避免的发生跨部门协作(服务器调用), 但是你怎么知道有这样一个部门可以做这个事情呢,就要依赖行政部门(注册中心),新成立的部门要在行政哪里做一个备案(服务注册),然后公布一下,让其他部门知道了(服务发布),大家就可以在新的工作秩序里面嗨皮的上班了,这个时候依然是在公司的组织架构中运转;

上述就是我理解的SOA的概念微服务没有具体的实施过,通过自己的一些理解尝试解释一下,勿喷!微服务有一定SOA的概念在里面,只是在粒度中,微服务更加细一点,比如说用户业务服务:登录 注册 个人中心 包含3个业务,都有userService 提供的,但是在微服务中,登录会被独立出来一个服务,注册也会被独立出来,相对SOA的粒度更细,业务场景耦合更低;另外微服务强调一个去中心化,上述的公司的组织架构会被打散,没有老板,没有管理层,每一个人都是一个服务,做着自己的事情,虽然没有完全想明白,把自己的理解放出来,大家可以探讨一下。

微服务是SOA的一种实现,也可以说微服务是去ESB的SOA

背后实际上是两种思想的分歧:分布还是集中

当然这里说的不是服务的分布和集中。服务肯定是分布的,这是大前提,是SOA的本质理念之一。分歧在于对服务的治理,是分布还是集中。

微服务所提倡的是完完全全的分布式服务。

微服务架构特征(Characteristics)

微服务架构是 Martin Fowler 和 James Lewis 定义的一种架构风格。他们将这种风格描述为”一种使用小型服务构建系统的架构方法,每个服务都在自己的进程中,它们通过轻量型协议进行通信”。

每个服务都是相互独立开发和部署的。每个微服务都专注执行一个它所擅长的相对较小的任务。

微服务架构是产品或服务所有者跟上或超越 IT 行业的快速发展节奏的推动因素之一。

小型且专注于业务领域

小并不能充分描述微服务,使用这个词只是为了尝试表明微服务相对于整体式应用程序的大小。在此上下文中,小的定义可能在各个系统中各不相同,而且没有规则来定义服务必须有多小。
我的理解是将传统整体式应用服务拆分为可独立运行互不干扰的最小组件,这个组件涵盖软件设计的全部细节,前段后端数据端,开发者必须熟悉小组件设计的全部设计环节,这岂不是以后每个人都必须是全栈式开发人员?

微服务的另一个重要特征是,每个服务专注负责一项精细的业务。Vaughn Vernon 在他撰写的图书《实现领域驱动设计》中定义了术语业务领域。他将业务领域定义为,”某个组织执行的操作和它执行操作的环境。”他还指定,”每个组织都有自己独特的知识范围和操作方式。这个理解范围和它执行操作的方法就是它的领域。”被分解为微服务的单元实际上就是领域内的业务实体,这意味着每个微服务处理完成一个完整的业务任务。例如:Mortgage Services 是一个业务领域。Loan Origination 是该领域中一个可能的微服务。Loan Refinancing 可能是同一个领域中的另一个微服务。跨服务边界的调用和更改通常很耗资源,必须避免。拥有这些服务的团队成为相应业务领域或子领域的专家,而不是任意技术领域的专家。

微服务通常负责一个精细的工作单元,所以它在规模上相对较小。一条著名的指导原则是”两块披萨的团队规模”方案,意思是说,如果两块披萨不能将整个团队喂饱,那么这个开发微服务的团队可能太大了。微服务必须足够小,使得团队中的每个人都能理解该服务的整体设计和实现。另外,它的大小必须足以让团队在必要时轻松地维护或重写服务。

与技术中立

开发微服务的团队必须使用他们熟悉的技术。不要规定开发团队应该使用何种编程语言。让开发人员自由选择对任务最有意义的技术和执行任务的人。这种工作方式能够充分利用团队成员拥有的最佳技术和技能。微服务架构仍需要技术决策;举例而言,使用具象状态传输 (REST) 应用编程接口 (API) 访问更好一些(即RESTful API),还是使用某种类型的排队来访问更好一些?但是,一般而言,您可以为微服务架构选择广泛范围内的任何技术。

  • 具象状态传输 (REST)
    具象状态传输(REST,英文:Representational State Transfer)是Roy Thomas Fielding博士于2000年在他的博士论文中提出来的一种万维网软件架构风格,目的是便于不同软件/程序在网络(例如互联网)中互相传递信息。
    目前在三种主流的Web服务实现方案中,因为REST模式与复杂的SOAP和XML-RPC相比更加简洁,越来越多的web服务开始采用REST风格设计和实现。例如,Amazon.com提供接近REST风格的Web服务运行图书查询;雅虎提供的Web服务也是REST风格的。
    这个后期会将互联网WEB架构单独开篇讲解。

松散耦合

松散耦合对基于微服务的系统至关重要。每个微服务都必须采用使其与其他服务的关联很小的方式来设计接口。这样,在更改一个服务并部署它时,就无需更改和重新部署系统的其他部分。(完全可独立运行的最小服务组件)

为了避免服务之间的耦合,必须了解导致紧密耦合的原因。紧密耦合的一个原因是通过 API 公开服务的内部实现。这种公开方式将服务的使用者与它的内部实现绑定在一起,从而导致更高的耦合度。在这种情况下,如果更改微服务的内部架构,可能还需要更改服务的使用者,否则就会破坏使用者。这可能会增加更改的成本,给实现更改带来潜在隐患,进而增加服务中的技术债务。必须避免任何导致公开服务的内部实现的方法,以确保微服务之间松散耦合。

另一个错误是让服务的 API 太过精细。如果 API 太过精细,服务之间的调用可能变得太过频繁,也就是说,会通过网络执行更多的调用。除了前缀的性能问题,过度频繁的通信还可能造成紧密耦合。因此,设计服务接口的方式必须能够最大限度地减少网络中执行的来回调用。

必须避免一个服务内的实现过于分散,方法是将表示业务实体的相关属性、行为放在尽可能相近的地方。将相关属性放在一个微服务中;如果更改某个属性或行为,可以在一个位置更改它并快速部署该更改。否则,必须在不同部分中执行更改,然后同时一起部署这些散乱的部分;这会导致这些部门之间紧密耦合。

每个微服务必须有自己的源代码管理存储,以及用于构建和部署的交付管道。这样即可在必要时部署每个服务,而不需要与其他服务的所有者进行协调。如果您有两个服务,而且始终在一次部署中一起发布这两个服务,这可能表明两个服务最好合并为一个服务,而且必须对当前服务执行更多分解工作。松散耦合还支持更频繁、更快速的部署,最终提高应用程序对其用户需求的响应能力。

实现容易观察

微服务架构要求您能够可视化系统中所有服务的健康状态,以及它们之间的连接。这使您能快速找到并响应可能发生的问题。实现可视化的工具包含一种全面的日志机制,能够记录日志,存储日志,并使日志容易搜索,以便执行更有效的分析。

向系统中配置和添加的新服务越多,让这些服务变得可观察就会越难。因为在添加更多动态部分时,微服务架构会增加复杂性,所以观察设计必须明确,使可视化的日志和监视数据能为分析提供有帮助的信息。

自动化

自动化是有效设计和实现软件应用程序的一个重要要求。对于微服务,自动化是一个至关重要但又充满挑战的任务。除了需要在生产中运行系统之外,微服务架构还向系统的实现引入了更多复杂性。在处理的机器和组件数量较少时,可能可以接受手动配置机器,安装中间件,部署组件,或者手动登录到服务器并收集日志,以及执行其他手动任务。但是,当组件数量增加时,在某个时刻后,您可能无法使用手动方法。

自动化可帮助组建一个服务器并安装必要的运行时环境。然后,只需使用几行代码,就能快速将微服务放在这些运行时环境上。这种自动化使您能编写微结构代码,访问用于部署生产服务的准确的工具链,从而及早发现问题。自动化是连续集成和连续交付方法的核心推动力量。如果您想将微服务架构的复杂性保持在控制范围内,推崇自动化文化是关键。为此,您需要一种综合的、端到端的方法,以便在整个软件开发生命周期中推广自动化。这个生命周期涉及通过一些操作执行测试驱动开发,比如 IBM Bluemix® Garage Method。有关更多信息,请访问网站。
https://www.ibm.com/cloud/garage/

有界上下文

开发模型时,请记住识别它的有界上下文,即模型的有效范围。有界上下文是具有明确边界的模型,模型在该边界内是没有歧义的。如果您不在模型周围设置一条边界,最终使用的上下文可能不在您的应用程序内。适合应用程序的某个部分的上下文不得适合另一个部分,即使它们具有相同的名称,而且指向相同的实体。例如,如果您构建一个预约系统,则必须知道客户的基本信息。但是,如果您在账单上下文中有一个账单系统,您可能希望在其中包含客户的联系信息和支付信息,而在预约系统上下文中,不需要该信息。如果您尝试在多个地方重用完全相同的客户模型,可能会在系统中导致不一致的行为。这是一个放入预约系统的上下文中的简单模型,包含一些除客户名称外的行为。

例如,您可能决定在客户模型上包含某种形式的验证,以确保拥有足够的信息来向他们收账。如果您不够小心,验证可能意外地阻止您使用客户模型安排预约;这不是那您想要的行为。账单系统可能要求客户拥有有效的信用卡,然后才能保存更改。但是,如果缺少信用卡信息,则会阻止您将客户预约信息保存到预约系统中,这是不合理的。

在这个示例中,您有两个上下文,但它们之间的边界是模糊和重叠的。Eric Evans 在他撰写的图书《领域驱动设计》中说道”模型仅在特定的上下文内有效。因此,最好显式定义应用该模型的上下文。您可以避免损坏该上下文内的模型,将它严格保持在这些边界内,并避免被外部问题分心或混淆。”

当显示定义了有界上下文后,通常能看到您是否拥有一个尝试扩展到多个上下文中的模型元素。在这个示例中,您希望在预约系统中保持简单的客户视图,而在账单上下文中提供包含联系信息和账单信息的更完整的客户视图版本。在两个不同的类中定义客户的这两个视图,然后将它们放在不同的应用程序中。Eric Evans 建议,通过为每个上下文提供它们自己的团队、代码库、数据库模式和交付管道,让有界上下文保持分离。

有界上下文的原则在微服务架构中至关重要。可使用这些原则作为指导,正确地确定系统并将其分解为微服务。明确定义有界上下文(意味着业务领域是通过显式边界分离的),有助于推断系统中最终包含的微服务。拥有有界上下文,还有助于正式化不同服务之间的交互,有效且高效地构建它们之间的接口。

1.通过服务实现组件化
传统实现组件的方式是通过库(library),传统组件是和应用一起运行在进程中,组件的局部变化意味着整个应用的重新部署。 通过服务来实现组件,意味着将应用拆散为一系列的服务运行在不同的进程中,那么单一服务的局部变化只需重新部署对应的服务进程。 另外将服务作为组件可以更明确的定义出组件的边界,因为服务之间的调用是跨进程的,清晰的边界和职责定义是设计时必须考虑的。

即单一服务可以作为一个单独进程存在。

2.按业务能力来划分服务与组织团队
康威定律(Conway’s law)指出:

organizations which design systems … are constrained to produce designs which are copies of the communication structures of these organizations.
任何设计系统的组织,最终产生的设计等同于组织之内、之间的沟通结构。

传统开发方式中,我们将工程师按技能专长分层为前端层、中间层、数据层,前端对应的角色为UI、页面构建师等,中间层对应的角色为服务端业务开发工程师,数据层对应着DBA等角色。事实上传统应用设计架构的分层结构正反应了不同角色的沟通结构。 而微服务架构的开发模式不同于传统方式,它将应用按业务能力来划分为不同的服务,每个服务都要求在对应业务领域的全栈(从前端到后端)软件实现,从界面到数据存储到外部沟通协作等等。因此团队的组织是跨功能的,包含实现业务所需的全面的技能。

近年兴起的全栈工程师正是因为架构和开发模式的转变而出现,当然具备全栈的工程师其实很少,但将不同领域的工程师组织为一个全栈的团队就容易的多。

3.服务即产品
传统的应用开发都是基于项目模式的,开发团队根据一堆功能列表开发出一个软件应用并交付给客户后,该软件应用就进入维护模式,由另一个维护团队负责,开发团队的职责结束。 而微服务架构的倡导者提议避免采用这种项目模式,更倾向于让开发团队负责整个产品的全部生命周期。Amazon 对此提出了一个观点:

You buidl it, you run it.
开发团队对软件在生产环境的运行负全部责任,让服务的开发者与服务的使用者(客户)形成每天的交流反馈,来自直接客户端的反馈有助于开发者提升服务的质量。

4.智能终端与哑管道
微服务架构抛弃了 ESB 过度复杂的业务规则编排、消息路由等(即去ESB化)。 服务作为智能终端,所有的业务智能逻辑在服务内部处理,而服务间的通信尽可能的轻量化,不添加任何额外的业务规则。

5.去中心统一化
传统应用中倾向采用统一的技术平台或产品来解决所有问题。 不是每个问题都是钉子,也不是每个解决方案都是一个锤子。 问题有其具体性,解决方案也应有其针对性。 用最适合的技术方案去解决具体的问题,在大一统的传统应用中其实很难做到,而微服务的架构意味着,你可以针对不同的业务服务特征选择不同的技术平台或产品,有针对性的解决具体的业务问题。

6.基础设施自动化
单一进程的传统应用被拆分为一系列的多进程服务后,意味着开发、调试、测试、集成、监控和发布的复杂度都会相应增大。 必须要有合适的自动化基础设施来支持微服务架构模式,否则开发、运维成本将大大增加(硬件水平跟上软件速度)。

7.Design for failure
正因为将服务独立在不同的进程中后,引入了额外的失败因素。 任何时刻对服务的调用都可能因为服务方不可用导致失败,这就要求服务的消费方需要优雅的处理此类错误。 这其实是相对传统应用开发方式的一个缺点,不过随着一些开源服务化框架的出现,对业务开发人员而言适当的屏蔽了类似的错误处理,不过开发人员依然需要知道对服务的调用是完全不同于进程内的方法或函数调用的。

8.进化设计
一旦采用了微服务架构模式,那么在服务需要变更时我们要特别小心,服务提供者的变更可能引发服务消费者的兼容性破坏,时刻谨记保持服务契约(接口)的兼容性。 对于解耦服务消费方和服务提供方,伯斯塔尔法则(Postel’s law)特别适用:

Be conservative in what you send, be liberal in what you accept.
发送时要保守,接收时要开放。
按照伯斯塔尔法则的思想来设计实现服务调用时,发送的数据要更保守,意味着最小化的传送必要的信息,接收时更开放意味着要最大限度的容忍信息的兼容性。 多余的信息不认识可以忽略,而不应该拒绝或抛出错误。

微服务架构应用

采用微服务架构面临的第一个问题就是如何将一个单一应用拆分为多个服务。 有一个一般的原则是,单一服务提供的功能是可以独立被替换和升级的。 也就是说如果有 A 和 B 两个功能,如果 A 功能发生变化时同时 B 功能也需要变化,那么 A 和 B 这两个功能应该被划在一个服务中。

微服务架构应用的成功经验近年已越来越多,例如国外的 Amazon,Netflix,国内如阿里都采用微服务架构取得了很多正面的成功案例。 但通过上文所述微服务架构特征看出,其实微服务架构模式有利有弊,需要根据实际的业务、团队、环境进行仔细权衡利弊。 其中的服务拆分带来的额外开发、测试、运维、监控的复杂度,在现有的环境、团队下是否能够很好的支持。

另外,有人可能会说,我一开始不采用微服务架构方式,而是在单一进程内基于清晰定义的模块化方式,模块之间通过接口调用,到了适当阶段,必要的时候再将模块拆分为服务。 其实这个想法显得过于理想,因为进程内良好定义的接口通常不是很好的服务化接口。 一开始没有考虑服务化的设计方法,那么后期拆分时依然是一个痛苦的过程(改整体架构对一个已成型的产品来说比开发一个新产品还要吃力)。

难在架构,也赢在架构!

总结

正如,Martin Fowler 在其文中所说,微服务架构是否就是企业应用开发的未来,还有待时间的检验。 就目前的情况看,对此我们可以保持谨慎的乐观,这条路依然值得去探索。 实际任何的架构决策都是基于我们不完美的现状做出的,这正是架构取舍的微妙之处,超越任何的方法论。

在整体式应用程序中,大部分逻辑都部署在一个集中化、单一的运行时环境或服务器中,并在其中运行。整体式应用程序通常很大,由一个大型团队或多个团队构建。采用此方法,各个团队需要花更多精力和统筹安排才能执行更改或部署。

随着时间的推移,整体式模型中已引入了更好的架构模式,有助于显著提高架构的灵活性。例如,一种著名的模式是模型-视图-控制器 (MVC),它将应用程序分解为层和合理的组件。这些模式有多种优点,比如更快的初始开发、更简单的应用程序治理,等等。但是,整体式模型也有缺点,尤其是在当今环境中的技术瞬息万变的背景下。(MVC【模型-视图-控制结构的整体式模型】已经不满足当前网络开发的情况了)

整体式方法可能带来许多挑战,有以下四点:

  • 庞大的应用程序代码库
  • 庞大的代码库可能给希望熟悉代码的开发人员带来困扰,尤其是团队的新成员。庞大的应用程序代码库可能还会让应用程序开发过程中使用的开发环境工具和运行时容器不堪重负。最终,这会导致开发人员效率降低,可能会阻止对执行更改的尝试。
    开发人员在进入这个项目业务时,因为是整体式的架构项目,开发人员可能负责的是整个控制层,业务层或者持久层的逻辑,虽然各层的处理逻辑和分类管理做的好的项目容易看得懂,但是各层的代码库随着产品的深入会加上各种功能,导致代码库庞大且凌乱,这就是导致了开发人员的工作重点不是在有效的开发上而是在找代码甚至是理清他们的关系上,开发效率低下也导致无用功过多,也会使开发人员的情绪受到影响。

  • 不频繁的更新

  • 在典型的整体式应用程序中,大部分(几乎是全部)逻辑组件都部署在单一运行时容器中,并在其中运行。这意味着要更新对某个组件的一处细微更改,必须重新部署整个应用程序。另外,如果需要推广细微但关键的应用程序更改,则需要投入大量精力来对未更改的部分运行回归测试。这些挑战意味着整体式应用程序很难连续交付,这导致部署次数减少,对需要的更改的响应变慢。
    利用微服务架构后若出现问题则可以单个组件更新部署,不需要整个项目进行维护升级。

  • 依赖单一类型的技术

  • 对于整体式模型,由于应用更改方面的挑战,以增量方式采用新技术或技术栈开发框架的新版本会变得很困难。最终,整体式架构应用程序通常必须一直使用这一种技术,这最终会阻碍应用程序跟上新的发展趋势。
    微服务架构利用各项技术优势互补,哪个效率高用哪个。新技术增加的功能可以直接部署在系统上,各组件的技术也可以用不同的语言来实现。
    甚至是为整个项目整体更换新框架时也会变得容易。

  • 可扩展性

可扩展性是整体式架构面临的最大挑战之一。Martin Abbot 和 Michael Fisher 在他们合著图书《可扩展的艺术》中介绍了一种查看系统的可扩展性的有用方式;他们使用了一种三维可扩展性模型或扩展立方体。在此模型中,通过在负载平衡器后运行克隆版本来扩展应用程序称为 X 轴扩展或水平复制。另外两种扩展是 Y 轴扩展(或功能分解)和 Z 轴扩展(或数据分割),Y 轴扩展通过拆分不同实体来实现扩展,Z 轴扩展通过拆分类似实体来实现扩展。由于整体上的凝聚性,典型的整体式应用程序通常只能在扩展立方体的一个维度上扩展。随着生产环境收到更多请求,该应用程序通常采用的垂直扩展方式是添加更多资源供其使用,或者克隆到多个副本来进行响应。这种扩展方式低效且很耗资源。
当应用程序达到一定规模时,开发团队必须拆分为更小的团队,每个小团队专注于一个特定的功能区域,各团队彼此独立工作,而且通常位于不同地理位置。但是,由于应用程序的各部分间的自然凝聚性,需要各个团队协力执行更改和重新部署。

logo

使用微服务架构的最重要目的是,解决整体式模型面临的难题。
将从应用程序的不同涉众角度,介绍微服务方法如何帮助解决整体式系统的问题。

  • 对于业务所有者

作为业务所有者,您希望您的服务适用于新客户和业务需求。但是,在整体式模型中,由于庞大的代码库,为满足业务需求而执行并推广更改的过程会很缓慢。这个过程缓慢的另一个原因是,各个组件和层之间有严格的内部限制和依赖关系。

依靠传统框架来将各个层和组件整合起来,这样的话各层的关系不仅会受到整体框架的限制,还会让开发周期变得很长。

微服务架构原则是围绕高灵活性和恢复能力而建立的。这两个特征有助于快速推广更改。这有助于业务所有者更快地收到反馈,调整业务和投资战略,从而让客户满意和提高市场竞争力。

从资源分配的角度讲,由于团队更小且更专注,所以可以更轻松地测量和可视化效率。然后,业务所有者可以更轻松地制定投资决策,可将资源从低业务影响区域转移到高业务影响区域。

  • 对于服务管理人员

作为服务管理团队成员,您希望协调各个团队的管理操作负担更少,以便您可以提高服务的生产力。整体式模型需要做大量的工作。活动之间需要的协调更多,因为整体式应用程序通常拥有庞大的业务范围,以及许多基础架构和操作接触点。因此,对应用程序的每次更改都可能需要不同涉众多次评审和批准。微服务架构推崇利用自助服务,在服务交付管道的每个阶段利用自动化

这有助于减少服务管理团队的日常管理协调。

微服务架构中的一个重要原则是高可观察性。高可观察性功能为服务管理团队提供了必要的工具,以便更好地监督系统中或产品中的每个微服务的状态。这有助于提高服务管理效率。

  • 对于开发人员

作为加入团队的新开发人员,您希望快速熟悉源代码,以便快速上手并带来成果。典型整体式应用程序中的代码库很大,可能阻碍您并潜在地延长学习曲线。对于所有开发人员,庞大的代码库会增加载入开发环境中并运行的负担,从而导致生产力降低。

庞大的代码库可能让代码评审和其他合作开发活动面临更大压力。此外,在处理更改时,破坏其他功能的风险可能导致开发人员对创新和增强应用程序犹豫不决。然而,微服务更小且更轻量,这可以缩短新开发人员的学习曲线。微服务还可以帮助消除加载和运行的繁重负担,鼓励引入突破性的更改,从而帮助提高生产力和创新水平。

———————————————更新线—————————————————

云时代

为什么现在是采用微服务架构的好时机。

  • 云环境和产品的激增

微服务架构体现了使用连续集成和连续部署的许多优势。该架构也引入了新的复杂性,需要一种在构建应用程序的每个步骤中实施自动化的现代方法。例如,从基础架构和治理的角度讲,首先需要一个能动态地快速为服务组建运行时环境的业务连续性基础架构。该环境可能是一个虚拟机、容器等。另外,还需要一种统筹安排和监视服务的高效方式。当今环境中的云平台(比如 IBM Bluemix)可通过其自然的动态性和恢复能力满足此需求。
借助可用于各种服务模型的不同云产品,无论是基础架构即服务 (IaaS) 还是平台即服务 (PaaS),开发人员都可以通过更多选择转变为微服务战略。借助 IaaS 选项,您可以在几分钟内快速组建一台机器,而且可以将基础架构配置打包到一组脚本中,以便根据需要自动化该流程。如果您不想接触基础架构级别的复杂性,也可采用平台级选项,采用不同的语言和服务的形式来快速打包,然后根据意愿包含和启动微服务。
IBM Bluemix 是这些平台的一个示例。IBM Bluemix 有许多适合使用云技术构建微服务的服务,比如 IBM 容器、消息中心、日志记录、监视和其他技术。Bluemix 使开发人员能够快速创建、部署和管理他们的云应用程序,为简化操作、确定安全策略和管理系统中微服务的健康提供关键基础。

  • 工具的可用性和成熟性

除了云基础架构可为微服务战略的采用所提供的动态性和恢复能力,拥有全面的工具也是采用微服务战略的关键需求。微服务工具在不断演变和进步。在当今环境中,开发人员有许多选择,他们可以使用一组合适的工具来实施其微服务战略,比如日志工具组合、监视工具组合、服务注册表或容器化技术。这些先进工具可帮助解决微服务架构所引入的挑战,以便更有效地交付、管理和统筹安排服务。
图展示了基于微服务架构而构建的 IBM Watson™ 云服务的完整组合示例。这种革命性架构有云技术、一组全面的工具及敏捷流程提供支持。

logo

该架构包含多个主要的技术组合:
DevOps
每个 Watson 云服务在开发后,都会在一个不可变的虚拟机中容器化,然后通过明显的 DevOps 流程自动部署到 IBM SoftLayer 云基础架构上。微服务架构的典型模式(比如服务发现、API 网关等)是通过 IBM 独有的和开源的技术来使用的。然后,可以在 IBM Bluemix 平台上公开这些服务。
Elasticsearch、Logstash、Kibana (ELK) 组合或 Elastic 组合
Elk 组合是该系统的日志工具组合,包含一组工具来捕获日志,并将其存储在一个强大的、集中化的、可搜索的日志数据库中。有关更多信息,请查阅 elastic 网站。
监视工具组合
展示了一组工具,它们可从一个中央仪表板监视整个系统,包含一种通知机制,以便基于特定事件来发送提醒。

从整体式应用程序向微服务的转变

  • 虚构公司 A 的业务问题
  • 虚构公司 A 是一家电子商务公司,它使用了一个名为 Customer Order Service 的基于 Java EE 的传统 Web 应用程序来提供在线购买服务和运营业务。尽管该应用程序能很好地处理业务,但公司 A 已开始努力响应新的业务需求。这些需求包括:

接触使用移动设备的客户
基于对客户在互联网上的个人行为的洞察,改善客户体验
扩展基础架构,以便处理来自新客户和现有客户的更多请求保持较低的 IT 成本
以及其他需求
目前的客户订购服务应用程序的设计不支持在业务领域中执行更改,而且无法应用新技术来加速创新。图中介绍了当前的整体式应用程序的逻辑架构概述。

logo

公司 A 希望改变客户订单服务应用程序,以便从业务和技术角度促进和更好地处理更改,它拥有一些主要的业务需求:

新系统必须是经过进化的,意味着它必须能灵活地处理更改。
在将流量从当前系统转移到新构建的系统的过程中,不允许宕机。
新应用程序必须能基于发送给系统的有效负载来按需或自动扩展,以便应对动态的购物行为模式。
新系统必须支持利用新兴技术来促进创新。

采用微服务来实现一种革命性架构:

采用微服务架构的主要动机是,解决很难更改的传统整体式架构的问题。微服务方法支持对架构的每个组成部分执行更改。对于业务需求,公司 A 非常适合在构建新系统时采用微服务架构。

公司 A 应用最佳实践和模式将现有的整体式应用程序转变为更加革命性的架构,以期最终将应用程序迁移到微服务架构上。
执行以下主要步骤和活动:

  • 演化战略
    要拥有一种转型案例分析中的整体式应用程序的合适战略,必须发现和考虑不同的模式和建议实践。

识别要转变为微服务的候选功能
在这一步中,选择应用程序的相对较小的组件或功能片段。从这些功能片段,可配置新微服务来让这些片段更有利于经常或渐进式的更改。

  • 数据访问模式
    因为数据是 IT 系统中最重要的资产,所以一个关键步骤是在转变为微服务架构的过程中采取正确的数据访问方法。

  • 安全和治理
    “安全和治理”将介绍如何在更加分布式的新模型中管理应用程序的组件,以及如何处理安全挑战。

  • 性能和可扩展性
    解决整体式应用程序的可扩展性问题时,微服务架构(拥有更多分布式特征)带来了性能挑战。

  • DevOps 和自动化
    自动化是让微服务方法成为可能的推动因素。

重点介绍了微服务的重要概念、特征以及它为何对现代软件应用程序的开发如此有吸引力的原因。最后,通过一个示例简单的描述了从整体应用程序向微服务的转变。目前为止,相信您已经对微服务有一个初步的了解。下一部分将更深入的介绍如何在 Java 中创建微服务。

内容转自 Evolve the Monolith to Microservices with Java and Node (IBM产品devoloper开发红皮书)

坚持原创技术分享,您的支持将鼓励我继续创作!
+