在《微服务的好处》这篇新闻中,我们曾经介绍了由 XebiaLabs 所组织的一次名为“探索微服务的未知边界”的在线研讨。Randy Shoup 是Randy Shoup 咨询公司的顾问CTO,之前曾在Google 担任云计算的工程师总监,他与来自XebiaLabs 的产品管理部门副总裁Andrew Phillips 共同回答了研讨会参与者所提出的有关微服务的一系列问题。我们对这些问题进行了编辑与摘录,可以在这里(PDF)下载到完整的问题。
如何比较微服务架构与传统的n**** 层架构?
Shoup 认为微服务架构是一种“让互相独立的服务进行协作的生态系统,而不是一种严格的分层模型”,其中每个微服务实现“一个功能块,并且只实现一个功能块”。他同时也认为在多个微服务之间共享直接的数据访问功能是一种反模式。
Phillips 进一步表示,虽然一个微服务能够应对一种商业需求,但在每个微服务中可以包含多个层,例如“一个持久化组件,一个 web 组件,一个业务逻辑或服务层等等。”
如果某个服务调用失败,如何保证数据的完整性?
Shoup 强调了“只让一个单一的(逻辑)系统处理每一份数据记录”的重要性,但数据可能会缓存在整个系统中的多个不同的位置。有必要让某个“可靠的事件系统”在原始数据出现变更时通知所有的相关服务,因此这些服务不会操作无效的数据。如果某个复杂的事务牵涉到了多个微服务,这个可靠的事件系统会确保对应的“业务活动最终能够正确完成”。
Phillips 则推荐了一种不同的方式,让系统中“最接近面向用户的组件”在某个变更发生时负责更新整个系统中的数据,它将对每个对该变更感兴趣的微服务发起调用,并传递相关数据的一份拷贝。他也承认这种做法会让面向用户的组件变得更为复杂,但同时也能够将传播数据变更的职责固定在一个地方。因此如果某个服务调用失败,也能够更容易地决定要如何进行处理。
在使用微服务时,是否有可能会最终产生一个未完成的用户订单?
如果在创建订单的过程中包含了多个微服务,Shoup 建议的做法是维护一个“包含多种订单的中间状态的状态机”。但他同时表示,更简单的做法是使用某个订单微服务,让它管理与订单相关的所有一切功能。它可以负责自己创建订单,也可以协调对其它与这一操作相关的微服务的调用。
Phillips 认为,如果在处理订单的过程中牵涉到了多个微服务,那么负责订单的微服务需要侦听与订单相关的事件,如果对这个订单进行了某种操作,该服务将负责更新这个订单的状态。
微服务是一种架构风格还是一种 SOA**** 的实现策略?
Shoup 认为它两者都是:
微服务这种方式本身就具有很强烈的架构方面的含义,它保持组件的小型化,并且避免使用共享的持久化数据。与此同时,微服务也是一种正确的 SOA 实现方式,每个服务都是简单的、可组合的,并且自包含的。“微服务”只是对传统的封装这一概念的一个全新的名称。
Phillips 表示,“对于微服务和 SOA 的定义有各种各样的细微差别,因此对这个问题的答案千变万化。”他进一步表示“SOA 与微服务两者都是强调独立服务的架构风格,但对于需要保持独立的服务类型的关注点并不相同:SOA 专注于独立的技术系统,而微服务专注于独立的业务系统。”
如何管理微服务之间的依赖的整个图形结构?
Shoup 认为“了解整个生态系统”是没有必要的,只需了解每个微服务的“传入与传出的依赖”就够了。重要的是“对协议、格式、安全特性等等进行标准化”。可以通过一个监控系统密切注视在系统运行中发生的一切事情,并且为了量化微服务中的任何变更所产生的影响,需要考虑到使用它的客户端。
Phillips 认为,“要完全理解真实世界中的任何一种微服务架构都是一件过于复杂的任务”,因此应当试图去理解本地的依赖。可以通过监控工具在运行过程中实现这一点,“尤其是在使用事件传播作为服务之间的异步通信机制的环境中,可以使用消息跟踪工具实现目标。”,他以 Netflix 的微服务管理方式作为示例。
Phillips 还指出,在尝试测试或部署微服务时,要保持它的“本地环境”的一致性,而无需通过某种工具去试图掌控包含了几十个、乃至数百个微服务的整个系统。
如果你打算将 A 服务部署到某个环境中,并且你知道 A 服务需要与两个 API 的特定版本进行通信(你也可以说“与另外两个服务通信”,但一般来说 API 这种说法对于服务的提供者或消费者来说更直接),那么实现以下功能是有可能的:a) 描述这种依赖 b) 使用某种工具或更好的技术来校验这种依赖 c) 通过将那些能够提供必要的 API 的服务的特定版本与你的应用一同部署在目标环境中的这种方式,自动确认所有的依赖都已就位。
如何将批量数据从微服务中传到数据仓库中?
即使需要传输大量的数据,Shoup 依然相信使用者不应当“绕开公开的服务接口,而直接对微服务的持久化存储机制进行读写”,而是应当通过所支持的接口进行操作。这种情况下或许可以使用某种更高效的传输协议,但仍然需要访问该微服务的公开接口。
Phillips 同意 Shoup 的看法,他提到了 Amazon Glacier 作为例子,“这是一种用于存储的 API,它在进行批量存储时的资源占用非常低”,它提供了“异步的 API 调用机制,这些调用过程可能会长达 24 小时,因为在后台需要有一个 robot 从存储系统中获取磁带。”
为什么要将变更分解为多个小步骤?
Shoup 认为,要交付优秀的软件,微服务、持续交付、敏捷实践和 DevOps 这些方法能够进行互补。在实现微服务时,“每个变更都控制在边界之内,并且易于理解,因而也更容易采用持续集成或持续交付流程”,将一个较大的特性分解为“多个小步骤,那么每个步骤都是易于理解、实现、测试以及部署的。”
Phillips 认为,人们之所以认为某些特性“非常庞大”,是因为要将它们部署到生产环境中需要消耗巨大的精力:“如果将某个特性部署到生产环境的过程需要整个会议中的 25 个人耗费一周的时间,那么要想通过改变一行代码就解决这一问题是不可能的。”他支持将特性控制在小范围的想法,这样能够让变更显得更简单,并且通过工具就能够自动地将这些变更部署到生产环境中,而无需人工干预。
你们如何定义微服务架构?
Shoup:“一种松耦合、面向服务、由多个边界上下文所构成的架构。”
Phillips 引用了 Martin Fowler 的定义:“一种软件应用程序的设计方式,由多个可独立部署的服务组成。”
你们对于微服务之间的通信有什么样的建议?
Shoup 认为在生产环境中多数会使用基于 HTTP/REST/JSON 的同步通信方式,使用异步方式的情况较少。
Phillips 则表示“没有一种唯一的最佳选择。”重要的是“尽可能对所使用的协议进行标准化,这会大大简化管理以及监控整个系统的复杂性。”
TDD**** 是否适用于微服务架构?
Shoup:“微服务本身非常适合使用 TFD 或 TDD,因为微服务就是一种自然的测试边界,很容易就能够实现完整的测试。”
Phillips 认为微服务很容易进行单独测试,但要“搞清楚如何测试依赖于多个相互通信的微服务的用户场景则是非常有挑战性的,因为如果你一上来就要搭建一个能够运行的测试环境,那么你需要协调多种不断变化的功能点。”
你们是否推荐使用某种治理结构,例如服务等级协议(SLA)?
Shoup 不推荐使用某种自顶向下的控制结构,因为它会成为整个开发和部署流程中的瓶颈。而是对“创建某个微服务时所使用的某种(受到支持的)通用库的集合”进行标准化,他建议以 Neflix OSS 项目作为起点。他也是 SLA 的强烈支持者,因为 SLA 让客户对微服务的期望变得清晰。
Phillips 认为,除了公开的接口之外,让某种“契约”指定客户所期望的性能参数是“至关重要的”。
Web service**** 与微服务之间有什么区别?
Shoup:“这两个概念是互不相干的。Web service 是通过某种 web 协议,例如 HTTP 所暴露的服务。而微服务是一种小型的、简单的、可组合的服务。许多微服务在实践中都是 web service,但只有部分 web service 可以称为微服务。”
Phillips:“并非每种微服务都是 web service。你的微服务所选择的通信协议取决于它的功能。”
关于受访者
Randy Shoup**** 是KIXEYE 的首席技术官,职责是打造优秀的游戏,提高它们的可伸缩性和可靠性。之前他曾是 Google 的工程师总监,领导多个团队致力于打造 Google App Engine 这个世界上最大的平台即服务功能。在加入 Google 之前,他在 eBay 担任了 6 年半的首席工程师,创建了连续几代的 eBay 实时搜索引擎。
Andrew Phillips**** 是XebiaLabs 的产品管理副总裁。Andrew 是 DevOps、云计算以及自动交付实践方面的一位福音传教士和一位精神领袖。Andrew 是管理团队的一员,负责驱动产品的发展方向、定位与计划。可以在此处看到关于他的更多介绍。
查看英文原文: Randy Shoup and Andrew Phillips Answer Questions on Microservices
评论