本文来源于我在InfoQ中文站翻译的文章,原文地址是:http://www.infoq.com/cn/news/2016/02/introducing-frock
Urban Airship是一家帮助领导品牌吸引其移动用户的公司,他们能够帮助这些公司在客户下载完应用后就与公司建立起高价值的关系。
眼下,Urban Airship已经有了数量庞大的客户群,涵盖的领域有零售业、媒体与娱乐、运动与旅游、医疗等。这些公司都通过Urban Airship来增强其与客户的连结性。近日。来自于Urban Airship的开发人员开源了他们所使用的一款开发工具:frock。该框架用于简化模拟服务套件的管理。
假设你在工作中使用了面向服务的架构,那么frock是很值得你去尝试的一个工具。
解决开发环境的复杂性
Urban Airship使用了微服务,这对于一家SaaS公司来说是很常见的模式:我们有许多服务,每一个服务都包装了少量的功能,而且每一个服务都能通过定义良好的协议为其它服务所请求。这对于可伸缩性与稳定性来说是很棒的,只是对于开发人员与其环境来说却产生了问题。我们的团队从事Go的开发工作(Go是Urban Airship Engagement仪表盘产品),它是最早期的Urban Airship代码基之中的一个,包括了大量的功能:消息生成与报告、账单与使用报告。以及服务管理(比方说前不久公布的Urban Airship Connect)。
Go会调用大量的服务。这导致团队的开发环境产生了许多问题。之前,我们的环境包括了一个单体的、执行于Vagrant之上的虚拟机。它依赖于仪表盘的全部服务。这么做有许多问题:
- 速度很慢。
服务与依赖的数量许多,包括几种不同的数据库都须要保持在执行状态才行。
- 很脆弱。我们的团队缺少JVM专家。
上游对服务的改动会破坏我们的开发环境,导致我们许多人都不敢更新。
- 导致开发人员无法继续工作。当开发人员的环境被破坏后,他们经常无法继续工作。
环境的复杂性意味着这样的破坏是会经常发生的。这会浪费大量的时间。并导致开发人员很沮丧。
- 难以将数据导入到环境中。
在开发阶段。你须要多种多样的数据来測试代码。
之前的环境通常要求你手工执行測试数据。这是通过与持有数据的服务进行直接的通信来做到的。
frock就是用来帮助我们解决上述全部难题的优秀工具。
何为frock?
我们能够通过frock使用自己定义的数据来模拟服务,使用团队习惯的语言与执行时来编写模拟服务:JavaScript与Node.js。
frock的核心仅仅提供了例如以下一些功能:
- 高度可配置的路由,这使得我们能够轻松拦截对服务的调用。
- 基于插件的架构,它并未对怎样编写模拟服务进行强制性约束。
- 针对常见任务的开箱即用的通用插件。即一个静态文件server与一个代理server。
- 支持HTTP与Socket服务。
- HTTP中间件支持,能够自己定义服务或路由的行为。比方说,它提供了一个延迟中间件,能够延迟请求的时间。
全部这一切都是通过一个JSON配置文件(依据约定,该文件名称为frockfile.json)来配置的。而且通过包括了全部自己定义模拟服务的仓库进行共享。frock从grunt与gulp获得了灵感,其配置就位于你的项目其中。对于HTTP模拟来说,一个frockfile会包括一个简单的服务与路由定义。比方说:
{ "servers": [ { "port": 8080, "routes": [ { "path": "/api/devices", "methods": ["GET"], "handler": "frock-static", "options": { "file": "./fixtures/devices.json", "contentType": "application/json" } }, { "path": "*", "methods": "any", "handler": "frock-proxy", "options": { "url": "http://localhost:8052" } } ] } ] }
这是我们frockfile中服务定义的一个高度简化的版本号。在訪问Go仪表盘时。你实际上会命中一个高可用的代理:该代理会在内部将流量导向不同的服务,其中的主服务是Go。只是一些API路由则是由二级服务所处理的。
相比于在本地执行这个二级服务,我们能够通过frock选择这个路由,并使用模拟的版本号将其替换掉。在上述代码演示样例中,模拟的仅仅是个静态文件,它由frock-static通用静态server插件所处理。全部其它的请求则会直接转向本地执行的Go开发server,server的端口是8052。
编写frock插件
实际上。frock是我们解决这一问题的第2个平台,第1个平台是个名为“multimock”的工具。它是个单体Python应用,能够创建出多个服务线程,并在到达自己定义处理器之前将其传递给一些通用的转换函数。它能够解决不少问题,只是我们还是重写了它,最后才有了frock。为什么要这么做呢?这是由于在multimock中编写插件是很困难的事情。在编写frock时,我们的核心原则是“插件的编写应该保持简单,内建的假设越少越好”。frock通过对插件施加极少的限制来实现这个目标,而且将Node.js HTTP模块的简单性直接应用到了实现中。例如以下代码展示了最简单的一个frock HTTP插件,它仅仅是向命中路由的不论什么请求响应了“hello world!”而已:
// file ./hello-world.js module.exports = createPlugin function createPlugin (frock, logger, options) { return handler function handler (req, res) { res.end('hello world!') } }
假设之前编写过Node.js的请求处理器。那么上述代码就很easy理解了;该frock插件仅仅包括了一个返回路由处理器的工厂函数。
在上述frockfile演示样例中。我们将这个插件替换为静态文件server:
{ "servers": [ { "port": 8080, "routes": [ { "path": "/api/devices", "methods": ["GET"], "handler": "./hello-world" }, { "path": "*", "methods": "any", "handler": "frock-proxy", "options": { "url": "http://localhost:8052" } } ] } ] }
如今,对http://localhost:8080/api/devices的不论什么请求都会返回“hello world!”。
frock对我们的帮助作用
大的特性公布经常都是很复杂的:你经常要等待依赖的服务就绪。还要阅读怎样使用这些服务的规范。在快节奏的项目中,这意味着你要不断追赶集成的日期。当终于全部组件都就位后。你希望他们能够彼此调用成功。
Connect就是这样一个项目,frock能够帮助Web团队构建出令我们充满自信的项目,而且能够很好地实现集成。
事实上。上面所介绍的关于frock的一切都不是什么革命性的功能,只是frock却能够帮助我们以一种更简单的方式做到这些。
建议各位读者尝试一下,你会发现它在你的开发环境中是很实用的。frock README包括了一个高速起步指南,另一个内容丰富的文档与演示样例代码,能够帮助你高速起步。在项目中使用frock并实现自己的插件。