面向服务与微服务架构

背景

最近阅读了 Martin Fowler 和 James Lewis 合著的一篇文章 Microservices, 文中主要描述和探讨了最近流行起来的一种服务架构模式——微服务,和我最近几年工做的实践比较相关感受深受启发。本文吸取了部分原文观点,结合自身实践经验来探讨下服务架构模式的演化。html


面向服务架构(SOA)

面向服务架构 SOA 思想概念的提出已不是什么新鲜事,大概在10年前就有很多相关书籍介绍过。当时 java 企业应用领域 J2EE 依然是主流,应用程序被部署在庞大统一的符合 J2EE 规范的容器中运行,在单一进程中提供全部的功能。 而 SOA 提出的一些架构原则,在当时看来无疑是革命性的。 因为业已存在的大量单一庞大的应用,按照 SOA 的思想和架构原则来改造无疑至关于推翻从新开发一遍,在成本上很难接受。 所以早期的 SOA 一般和另一个术语关联在一块儿——ESB(企业服务总线)。 当时在 SOA 的实施思路上无一例外的选择了 ESB 模式来整合集成大量单一庞大的应用,以保护企业前期投入成本。所以 ESB 实际上是 SOA 特定历史阶段的一种实现方式。前端

然而,愿望老是美好的,现实却要残酷的多。过去这些年咱们看到了不少实施 ESB 搞砸了的项目,投入几百万,产出几乎为 0,所以 SOA 这个概念也蒙上了不详的标签。 近几年流行起来的服务化架构,其拥护者开始拒绝使用包裹着失败阴影的 SOA 这个标签,而称其为微服务架构(Microservices Architecture Style)。但事实上 微服务架构依然是 SOA 架构思想的一种实现。java


微服务架构(Microservices)

对微服务架构咱们没有一个明确的定义,但简单来讲微服务架构是:编程

采用一组服务的方式来构建一个应用,服务独立部署在不一样的进程中,不一样服务经过一些轻量级交互机制来通讯,例如 RPC、HTTP 等,服务可独立扩展伸缩,每一个服务定义了明确的边界,不一样的服务甚至能够采用不一样的编程语言来实现,由独立的团队来维护。


微服务架构特征(Characteristics)

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 过分复杂的业务规则编排、消息路由等。 服务做为智能终端,全部的业务智能逻辑在服务内部处理,而服务间的通讯尽量的轻量化,不添加任何额外的业务规则。模块化

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 在其文中所说,微服务架构是否就是企业应用开发的将来,还有待时间的检验。 就目前的状况看,对此咱们能够保持谨慎的乐观,这条路依然值得去探索。 实际任何的架构决策都是基于咱们不完美的现状作出的,这正是架构取舍的微妙之处,超越任何的方法论。

相关文章
相关标签/搜索