微服务平台:[仍然]需要一些组件

    使用微服务进行本地工作

  在过去的五年,我一直在使用一个基于“微服务”架构的几个项目中工作。有一个问题就是缺乏一个标准模式来进行本地开发,并且缺乏“现成的”开发工具来支持这一标准模式。当处理整个开发项目时,我们已经相当擅长于精简开发、构建、测试和部署周期,使用开发工具来帮助这些过程也是现成的(并且常常和我们的IDE集成)。例如很多平台提供“热重载”来查看以下事项效果:代码在接近实时的变化、自动执行测试、来自于持续集成服务的常规的本地反馈、以及工具,能提供模仿生产堆栈的本地环境。

    管道前(本地)开发过程

  如果看看为单片应用程序建立的一个典型管道,就会发现一个单片组件的流相对而言更容易实现。显然,当处理微服务时,管道会变得越来越复杂。我们在以后的博客中会涉及到这一部分,但现在看看管道前本地开发阶段,这个阶段最有可能涉及到多个互相依赖的服务同时工作。

  使用单片代码时,假设在一个本地开发计算机上进行创建和配置至少是与QA环境的配置一样容易的(如果不是,那么你应该问问为什么!)。本地开发计算机配置工具如GitHub的Boxen (Puppet)、Pivotal的 Sprout(Chef)、或mac-dev-playbook (Ansible)允许指定本地工具安装和标准化配置,或者通过使用Vagrant 或 Docker Compose(née Fig)虚拟本地环境,这使得建立一个堆栈变得相对容易。

  在微服务的世界里,这些开发任务的工具往往存在于一个组件/服务的层面。但当服务的数量(和种类)增加、服务之间依赖关系的数量增加时,或者当一个复杂的业务流程发生在一个包括好几个协调服务的较高的(系统)水平时,事情就会变得更具挑战性。

  使用微服务进行本地工作的五种模式

  幼稚(痛苦)的方法

  以我的经验,当大多数开发人员开始使用微服务时,他们只是试图为每一个新的服务复制他们的本地开发做法。我相信这是一个合乎逻辑的方法(而我已经做到了!),但与计算中的许多东西一样——手动复制只会让你不过如此。

  我在这种风格的工作中遇到的最大问题是测试的集成成本。即使每个服务都有集成/组件级别的测试,一旦你开发更多的服务,协调测试配置和初始化会变得非常困难。你会经常发现自己在本地编造外部服务(通过复制、建设和运行来自VCS的代码库),在这个状态周围瞎摆弄,在你正在开发的项目中运行测试服务代码,而最终验证着外部服务的状态。

  过去我见过很多开发人员试图通过创建简单的脚本文件(bash,Python,Ruby等)来解决这个问题,把所有事情搅和在一起并初始化数据测试。在我的经验中,这很快成为一个维护的噩梦,而并不是一个值得推荐的方法——我在这里只把它作为一个基线,所以继续往下读吧,读一读关于一个可扩展的方法……

  本地的“配置文件”结合模拟和存根

  如果你熟悉如何使用基于JVM的Spring框架(或Maven构建工具)来开发代码,你会立即发现“配置文件”的概念,但目前这种模式横跨了许多语言的栈(例如铁轨的“RAILS_ENV”或者Go's envconfig)。基本配置文件允许多个配置在生成或运行时开发和切换。这将允许你为本地开发的外部服务接口开发模拟或存根实现,并按需要将这一版本和所需的实际生产实现之间进行切换。

  我已用这种技术成功开发了基于java的电子商务“店面”服务,依赖于“产品搜索”服务。产品服务的接口有明确的定义,我们开发了多个配置文件,用于运行通过Maven /rake自动化测试:

  ●“无搜索”——这一配置文简单模拟了无操作的产品搜索服务(使用RSpec mockito或RSpec Mocks),并返回空的结果。当本地开发的代码与产品搜索服务进行交互时,这一点很有用。但是我们不关心从调用中返回的结果。

  ●“参数化搜索”——这一配置文件包含“产品搜索”的存根实现,我们可以在测试中参数化返回各种搜索结果(例如一种产品、两种产品、一个属性为X的特定产品、无效的产品)。我们创建的存根实现只是作为一个java类,并从外部的JSON数据文件加载预存的搜索结果。这是一个非常有用的模式,但如果存根开始变得复杂(附有许多条件),那么看看下面的“服务虚拟化”模式。

  ●“生产”——这是产品搜索界面的生产实现,与一个实际的服务实例进行了对话,并进行了适当的对象编组和错误处理等。

  虽然是不完全存根或模拟,我还要在这个模式中包括嵌入式或进程内数据存储的使用以及中间件。运行嵌入式程序通常会使你能够与这个组件进行互动,就好像你在运行一个完整的进程外的实例,但对于初始化开销或对外部配置进程的需要会少得多。我已经在使用H2作为MySQL的测试替代、Stubbed Cassandra 替代Cassandra、以及运行嵌入式 ElasticSearch节点中取得了许多成功。

  服务虚拟化

  当模拟或接外部服务变得复杂,这可能预示着将服务虚拟化会更加合适(如果你的存根开始包含许多条件逻辑,正在变成人们改变预存数据和打破许多测试之间的争夺点,或是正在成为一个维护问题,这可能预示着有太多的复杂性)。

  服务虚拟化是一种技术,可以让我们创建一个应用程序,将模拟外部服务的行为而不用实际运行或连接到服务。这种技术使得单独模拟或存根的复杂服务行为的管理更易于实现。我已经在许多案例中成功使用了这种技术。例如,当一个依赖的服务返回复杂(或大量)的数据时,当没有访问外部服务(例如它可能是由一个像SaaS这样的第三方拥有或运行)的权限时,或者当许多额外的服务将与这此依赖性相互作用而共享虚拟服务比模拟/存根代码更加容易时。

  这方面的工具包括:

  ●Mountebank——这个工具是一个Java/Node.js应用,提供“跨平台、多协议测试双打线”,而我已经使用它来虚拟化与HTTP / HTTPS和TCP对话(它也支持SMTP)的服务。API是易于使用的,虽然你写的一些代码看起来非常冗长,但是制作复杂的虚拟化反应非常容易。

  ●Wiremock——这个工具类似于Mountebank,它通过创建一个实际的服务器(本例中的HTTP)进行工作,该实际的服务器可被配置为应答一系列虚拟化反应。正如由另一个伦敦的开放源代码测试和Cassandra wizard、Chris Batey所证明的,这可以让你能够通过模拟你可能不会遇到的服务问题来测试你的服务失败和错误处理。

  ●stubby4j——这是一个很好的java聚焦工具,有很多与Mountebank和wiremock相似点。我个人没有过多使用这一工具,但我的几个OpenCredo同事在与外部遗留信息进行交互时使用了Stubby4j来模拟复杂的SOAP和WSDL消息。

  ●VCR/Betamax——这两者都是非常有用的应用程序实现,允许你记录和重放网络流量。我发现当我没有访问的外部依赖服务代码的权限(因此我只能观察到我的请求的响应)时,当服务返回大量的数据(我可以用一个外部磁带进行捕获)时,或向服务呼叫受到限制或非常昂贵时,这些应用程序实现就特别有用。

  ●Mirage(原名为Stub-o-matic)--这是一个新的服务虚拟化应用,通过Wiremock和VCR提供额外的配置选项。我们已经在几个成功的项目中使用它来模拟响应复杂的遗留应用程序(我们都已经得到这些了,对吗?)。我们还将Mirage使用于执行负载测试。负载测试中一个外部的基于SaaS的应用测试沙盒处关键路径上,不允许我们在其不成为自身瓶颈的情况下提高请求数量。为了透明度的利益,这个工具正在Spectolabs开发。Spectolabs是一个与Opencredo联合的公司。

  “盒子-内-生产”

  这种模式使开发人员可以下载预存的服务图像到一个本地机器中,易于执行开发或运行测试。我们最初是与HashiCorp的 Vagrant开始做这个模式,在那里创建一个预先设定的vbox的图像,其包含一个应用程序的代码/二进制文件与一个操作系统、配置和相关的数据存储,这些在开发团队共享。Packer的到来使得图像创作过程更加容易,也使我们能够进行一次指定应用程序包,并在不同环境中重新使用(如在生产中的AWS,为QA的OpenStack,以及为本地开发的VirtualBox)。

  Docker的到来大规模推广了这种应用程序的封装和共享的风格,而Fig组件工具就是锦上添花。Fig已经演变为Docker 的组件,而现在它允许说明应用程序/服务的规范和关联关系以及数据存储。这种模式的确允许一系列的相关服务在本地开发机器上非常灵活的执行,而在我们的经验中,主要的限制因素是机器资源(尤其是当运行hypervised平台时)。

  “盒子-内-生产”模式也允许我们保持一个更加清洁的本地开发环境,并通过封装一个服务和它的依赖关系和配置来消除潜在的配置冲突(例如java版本的不同要求)。我们也可以parametrise图像(通过初始化参数和环境变量),就像在做上述“配置文件”模式一样,并允许服务按照需要进行运转。我们已经成功地将Docker插件用于maven和Ruby/Rake,使容器的生命周期与运行试验相集成。

  这种模式的一个潜在的扩展是开发实际的图像本身,例如通过安装本地源代码到图像的运行实例中。如果做得正确,可以消除在本地开发计算机上安装几乎所有的工具的需要(也许要除开你最喜欢的编辑器或IDE),并大大简化了构建工具链(例如你不必担心 GO_PATHS,或你正在运行的Python是什么版本)。如果你正在运行一个编译语言,那么就可以通过建立管道创建一个开发和生产图像。管道包含源代码或仅仅是二进制文件的分别链接。

  环境租赁

  简而言之,环境租赁模式是这样来实现的:允许每个开发人员创建和自动提供他们自己的远程环境。远程环境可以包含任意配置的服务和数据。服务和数据(以及相关的基础设施组件和胶质)必须指定以编程方式进行指定,方法是通过Terraform 或其中一个CAPS 工具(目前最喜欢的是Ansible);并且这种方法在团队中共享的知识必须是可行的,因此你必须融入DevOps思维。然后本地开发机器就可以配置为与安装在远程环境中的依赖项进行通信,就好像所有的服务都在本地运行一样。我们已经在部署应用程序到基于云的平台中使用了这种模式,这使我们可以按照需求打开和关闭环境。

  “平台租赁”模式是一种先进的模式,依赖于按需提供平台环境的能力(例如私有/公有云与弹性缩放)。它也需要开发人员的机器具有连接到这个环境的一个稳定的网络。我们还发现运行的本地代理,如与HashiCorp的Consul和consul-template相组合的Nginx或HAProxy,或者诸如与Netflix的 Eureka相结合的Spring Cloud 等框架。这对于实现自动存储和更新每个开发者的环境位置非常有用。

  总结

  本文试图总结我们在过去五年左右的时间里,使用微服务进行本地开发和工作的经验,是我们的“微服平台:[仍然]需要一些组件”系列的一部分。有了现有的工具和方法,使用一个或两个服务器在本地工作很容易实现。但在我们的经验中,除非我们利用上面记录的模式,编排和配置的复杂性会随着服务数量的增长而呈指数增长。

  除了上述关于本地开发模式的描述,我还附上了一个详细的PDF“备忘单”:

  本地开发人员计算机提供和配置 外部开发服务安装和初始化 数据存储/中间件安装和初始化 组件级别(集成)测试方法 终端对终端测试方法
幼稚的方法手动“雪花”配置VCS复制、建立和运行(以及视情况到处瞎弄和大声咒骂手动安装、配置和数据初始化为服务编排和数据配置(即管道胶和串)写复杂而脆弱的脚本手动部署服务到QA/阶段环境,且手动测试引导
本地的配置文件(单机)配置工具(Boxen,Sprout,mac-dev-playbook等等)使用带有预存储行为的Mockito, RSpec doubles或bespoke 存根等等进行服务模拟和存根使用配置工具(Boxen,Sprout等)或内存中变量(如H2,SQLite, Stubbed Cassandra)标准特定于语言方法(如maven 核实, rake测试手动部署服务到QA/阶段环境,且自动测试初始化
服务虚拟化配置工具(Boxen,Sprout,mac-dev-playbook等等)初始化服务虚拟,如Mountebank,Stub-o-matic,Wiremock/Saboteur, 或VCR通过配置工具或使用内存变量(如H2, Stubbed Cassandra)初始化服务虚拟/管理标准特定于语言方法(如maven 核实, rake测试),与服务虚拟化集成手动部署服务到QA/阶段环境,配置服务虚拟化选项(如“昂贵的”外部资源可以被虚拟化)自动测试初始化
“盒子内生产”配置工具(Boxen,Sprout,mac-dev-playbook等等),或为in-VM/容器开发安装Vagrant/Docker Compose下载VM/Docker图像并运行(如有需要使用参数)下载VM/Docker图像并运行标准特定于语言方法(如maven 核实, rake测试),与数据存储初始化(如DBUnit, rake db:setup)和服务API(为了指定预存储设备)集成手动部署服务到QA/阶段环境,自动测试初始化
环境租赁配置工具(Boxen,Sprout,mac-dev-playbook等等),或为in-VM/容器开发安装Vagrant/Docker Compose在租赁的环境中初始化服务,并配置本地代理(nginx,HAProxy)来指向租赁的实例(如:使用Consul 和consul-template)通过API在租赁的环境中初始化数据存储标准特定于语言方法(如maven 核实, rake测试),与数据存储初始化(如DBUnit, rake db:setup)——或——自动测试运行每一代码激活租赁的环境在共享的集成/阶段(或生产)环境中自动测试运行每一代码激活

  

本文作者Daniel Bryant,由寄云科技翻译。欢迎关注寄云科技订阅号(neuclouddy),这里有最新云服务行业资讯,更有与PaaS、运维相关的技术干货!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值