2015.5 技术雷达 | 技术篇

点击这里可以下载最新中文版本PDF

2015-5 技术

当多个独立开发的服务通过 API 交互的时候,API 提供端的改动会让它所有的消费端调用失败。消费端服务通常也不会直接去连接处于开发中的提供端服务来进行测试,因为这样的测试是缓慢且脆弱的(martinfowler.com/articles/ nonDeterminism.html#RemoteServices),因此最好的方式是采用测试替身(martinfowler.com/bliki/TestDouble. html),但这又引出了测试替身和实际的 API 之间失去同步的风险。消费端的开发团队可以通过使用集成的合约测试(martinfowler.com/bliki/IntegrationContractTest.html)来保护自己——其比较真实服务的响应和测试替身之间的一致性。这样的合约测试是非常有价值的,而更有价值的方式是消费端把它们的测试提供给 API 提供端——采用消费端驱动的合约(martinfowler.com/articles/consumerDrivenContracts.html),提供端可以运行所有消费端所提供的测试来验证自己的修改是不是有可能引起问题。这种消费者驱动的合约测试(consumer-driven context test)是成熟的微服务测试策略(martinfowler.com/articles/microservice-testing/)中非常核心的组成部分。

当我们需要一张描述当前系统的基础设施或物理架构的图形时候,我们通常会选用自己最喜欢的工具来绘制。但是当你使用云或者其他虚拟化技术的时候,这种方式却不再适用。我们可以使用这些平台本身提供 API 去查询实际的基础架构环境,并使用一些简单的工具比如 GraphViz(graphviz.org),一些可以输出 SVG 格式的工具,生成实时的,自动化的基础架构图(automated infrastructure diagram)。

离线优先 Web 应用程序(Offline first web applications)提供了基于缓存和更新机制来设计 Web 应用离线访问的能力。它的实现需要在 DOM 中设定一个标志来检查接入设备是否在线,离线则访问本地存储,在线则同步数据。现在所有的主流浏览器都支持离线模式,通过显示的指定 HTML 属性来使本地信息可访问,同时启动如 HTML, CSS,Javascript 或其他资源的下载和缓存。当前已经有一些工具使离线优先应用的实现变的简单,如 Hoodie(hood.ie),CouchDB(couchdb.apache.org),不仅如此它们还提供与本地部署的本地存储应用的集成能力。

大多数软件开发的心智模型都是做项目,在不同的档期内进行计划、执行和交付。敏捷开发极大的挑战了这种模型,通过与开发过程同时进行的持续需求发现,代替了预先的需求确定。精益创业的技术,如观察需求的 A/B 测试(martinfowler.com/bliki/ObservedRequirement.html),进一步削弱了这种心态。我们认为,大多数的软件开发工作应该遵循精益企业的引领(info.thoughtworks.com/lean-enterprise-book.html),将自己定义为构建支持业务流程的产品。这样的产品并没有所谓的最终交付,更多的是一个探索如何更好的支持和优化业务流程的过程,只要业务依然有价值就会不断持续下去。基于这些理由,我们提倡企业组织依照产品而不是项目(products rather than projects)的思路进行思考。

当前大多数开发团队都意识到编写安全软件并以负责任的方式处理用户数据的重要性。他们确实面临着陡峭的学习曲线和大量的潜在威胁,其范围从有组织的犯罪和政府的间谍活动到仅仅是为“玩笑或激怒什么人”而攻击系统的年轻人。威胁建模(Thread modeling)(owasp.org/index.php/ Category:Threat_Modeling)是一组技术,主要从防御的角度出发,帮助理解和识别潜在的威胁。当把用户故事变为“邪恶用户故事”时,这样的做法可给予团队一个可控且高效的方法使他们的系统更加安全。

Flux(facebook.github.io/flux)是 Facebook 为其互联网应用开发所采用的一种应用架构。它通常与 react.js 一同被提及,Flux 基于一个单向数据流,用户或外部事件对数据存储的修改会触发数据在渲染管道中向上流动。已经有好一阵子我们都没有看到任何古老的model-view-*架构的替代者了,Flux 拥抱这种 Javascript 前端应用与多个后端服务通信的现代互联网时代。

当前,大部分开发人员习惯使用 git 来管理源代码以及协作。但是,git 还可以为其他一些情况提供基础的实现机制,比如当人们需要使用基于文本化的文档进行协作的时候(这些文档可以被很容易的合并)。通过使用基于文本的可编辑格式,我们已经看到越来越多的项目把 git(git-scm.com)作为一个轻量化的 CMS 来使用。Git 有很多强大的功能,通过使用分布式的存储模型,Git 可以支持对变化的跟踪以及寻找替代品。然而,难于大范围采用 Git 的最大原因是 git 对于非编程开发人员来说并不容易学习,而我们期望看到更多的构建在 git 核心之上的工具的出现。这类工具可以为一些特殊听众简化他们的工作流程,如作为内容的作者。我们也欢迎更多的工具支持对比和合并非文本文档。

凤凰服务器(martinfowler.com/bliki/ PhoenixServer.html)的想法现在已经被很好的建立并且在被应用到一些正确的问题上时带来了很多好处。而我们要部署的服务器所依赖的环境,如在某些情况下需要等待网络配置、负载均衡、防火墙端口等等情况,却已逐渐成为修改配置时的主要瓶颈和限制。凤凰环境的概念可以帮助这种情况。它允许我们可以用自动化的方式创建整个环境并保证定期销毁和重建整个环境的流程正确,例如在AWS上使用CloudFormation。凤凰环境可以支持为测试,开发,UAT等等配置一个全新的环境。它也可以简化对灾难恢复环境的配置。由于凤凰服务器的模式并不总是可行的,我们需要小心地对待诸如状态和依赖,在蓝绿部署中用它对环境配置进行重置可以成为一种方式。

函数式反应型编程在过去的几年渐渐开始流行起来,同时这个概念越来越多被延伸到在分布式系统架构中。根据反应型编程宣言(reactivemanifesto.org),反应型架构(reactive architectures)主要基于通过一个网络下独立进程间的单向,异步的不可变事件流(可能具体实现为微服务)。在正确设置下,基于这种架构的系统容易扩展,具有弹性,也会减小了各个独立处理单元间的耦合。但是完全基于异步消息传递的架构同时会引入相应的复杂度,并且常常会依赖于一些专有的框架。所以我们推荐在选择这种架构风格前首先了解自己系统对于性能以及可扩展性的需求。

对于安全,传统的方式依赖于前期的需求规格以及最后阶段的验证。这种“安全三明治”的方式很难应用于敏捷团队,因为大部分设计都贯穿于整个过程,而且也没有持续交付所提供的自动化便利。公司或者组织应着眼于如何在整个敏捷开发周期中注入安全实践。这包括:正确评估当前威胁模型的级别以做前期设计;考虑何时将安全问题划分为独立的故事、验收标准、或全局的非功能性需求;在构建流水线中引入静态或动态的自动化安全测试;考虑如何将更深层次的测试,如渗透测试,引入到持续交付的发布过程中。正如 DevOps 的出现使得过去相互博弈的团队能够重新合作一样,同样的事情也正发生在安全人员和开发人员身上。(尽管我们并不喜欢安全三明治模型,但这也比根本不考虑安全要好得多,糟糕的是,这依然是一种非常普遍的状况。)

 

点击这里可以下载最新中文版本PDF

Share

2015.5 技术雷达 | 工具篇

点击这里可以下载最新中文版本PDF

0

尽管依赖管理的概念并不新奇,在很多技术栈下它甚至已经被作为一种基础开发实践,但在 PHP 社区却并非如此。Composer(getcomposer.org)作为 PHP 技术栈下的依赖管理工具,深受其他技术栈下依赖管理工具的影响。例如, Node 的 npm 以及 Ruby 的 Bundler 等。现如今 Composer 已经被 PHP 项目广泛使用,并且其本身也日趋成熟。虽然在对内部库的管理上,Composor 还有待改进,但是对于大多数外部库的管理 Composor 已能够完全胜任。

在企业级应用中,对组件进行良好的测试至关重要,尤其是对于服务的分离和自动化部署这两个关系到微服务架构是否成功的关键因素,我们更需要更合适的工具对其进行测试。“服务虚拟化”这一行业术语,意指能够在组件化服务的场景下模拟特定组件的工具。Mountebank 显然取得了不错的成绩。它是一个轻量的测试工具,可以被用于对 HTTP、HTTPS、SMTP 和 TCP 进行模拟(Mock)和打桩(Stub)。

 

Postman(getpostman.com/features)是一个在 Chrome 中使用的 REST 客户端插件,通过 Postman,你可以创建请求并且分析服务器端返回的信息。这个工具在开发新的 API 或者实现对于已有 API 的客户端访问代码时非常有用。Postman 支持 OAuth1 和 OAuth2,并且对于返回的 JSON 和 XML 数据都会进行排版。通过使用 Postman,你可以查看你通过 Postman 之前发起过的请求,并且可以非常友好的编辑测试数据去测试 API 在不同请求下的返回。同时,虽然我们不鼓励录屏式的测试方法,但是 Postman 提供了一系列的拓展允许我们将它作为跑测试的工具。

 

Brighter(iancooper.github.io/Paramore/Brighter.html)是一个基于.Net的开源工具库,主要实现了命令调用模式。我们从正在使用它的一些团队中收到了很好的反馈,尤其在与端口模式、适配器模式和命令查询职责分离模式(CQRS)一起使用的时候。特别值得一提的是,它还可以很好地与 Polly(github.com/michael-wolfenden/Polly)集成并提供熔断器模式的支持。

 

支持 DNS 和基于 HTTP 发现机制的服务发现工具 Consul(consul.io)持续让我们印象深刻。它提供了定制化的注册服务健康检查并标记不健康实例的功能远胜于其他类似的工具。更多时兴的工具与Consul的集成使其功能更加强大。Consul Template (github.com/hashicorp/consultemplate) 可以直接使用Consul的信息来填充配置文件,使得像用mod_proxy进行客户端负载均衡更加容易。在使用Docker的场景里,有了registrator (github.com/gliderlabs/registrator) 的帮助,只需要很小的工作量就可以自动化地向Consul注册Docker容器,使得管理基于容器技术的配置更加容易。

在我们软件开发领域,盲目地假设网络总是可靠,服务器总是能够快速并正确的响应导致了许多失败的案例。Hamms (github.com/kevinburke/hamms)是一个有趣的开源工具,它可以模拟一个行为损坏的HTTP服务器,触发一系列的失败,包括连接失败,或者响应缓慢,或者畸形的响应。它可以帮助我们更优雅的测试我们的软件在处理异常时的反应。

我们的多个使用.NET技术栈的项目已经在推广使用Polly(github.com/michael-wolfenden/ Polly)来帮助我们构建基于微服务的系统。它鼓励使用基于流畅表达式的透明错误处理机制,以及包含了多种断路模式(Circuit Breaker Pattern),如重试,不断重试,稍后重试。在其他语言中已经存在类似的程序库,如Java中的Hystrix,而Polly是.NET家族的一个很好补充。

REST-assured(code.google.com/p/rest-assured)是一个用于测试和验证RESTful服务的Java DSL。它使得为基于HTTP的RESTful服务编写测试变得更加简单。REST-assured支持不同类型的REST请求,并且可以验证请求从API返回的结果。它同时提供了JSON校验机制,用于验证返回的JSON数据是符合预期的。

 

ZED Attack Proxy(ZAP)(owasp.org/index.php/ OWASP_Zed_Attack_Proxy_Project)是一个OWASP的项目,允许你以自动化的方式探测已有站点的安全漏洞。可以用来做定期的安全测试,或者集成到CD的Pipleline中提供一个持续的常规安全漏洞检测。使用ZAP这样的工具并不能替换掉对安全的仔细思考或者其他的系统测试,但是作为一个保证我们的系统更安全的工具,还是很值得添加到你的工具集里。

 

相对于通过发送同步点对点请求的方式修改状态,最近许多企业级软件开发都在致力于基于异步不变事件序列的架构演进。Apache Kafka是一个开源消息框架,它支持基于有序的发布消息到许多独立的轻量级的消费方的架构风格。Kafka的独特设计使它能够在保持消息顺序强相关的前提下动态增加消费方的数量 。

 

Blackbox(github.com/StackExchange/blackbox)是一个用于加密源代码仓库中特定文件的简单工具。如果你需要存储密码或者私钥的时候,这个工具特别实用。Blackbox 可以和 Git,Merurial 和 Subversion 结合使用,并使用 GPG 加密。每个用户拥有自己的密钥,使得细粒度级别的权限撤销变得很容易。这个领域正在发生很多变化,一些其他的工具也可以考虑包含进来,如 git-crypt Trousseau

 

在数据科学和分析的世界里,大部分工作都是使用 Python 和 R 来完成,但是这两个语言只为 Web 可访问的可视化图形绘制提供了有限的几个支持。一种做法是将分析的结果转换成为能够在浏览器里很容易呈现和交互的格式。我们知道有两个工具来尝试这样做。Bokeh 是一个可以让你创建像 D3.js 一样风格的交互式可视化的 Python 和 JavaScript 库,但是在处理大数据集或者流式的数据集时,具有更高的性能。Vega 是一种针对 D3 的声明式可视化语法,它接收服务器端生成的 JSON 数据并将可视化描述转化为 D3.js 的代码。

 

Gor是一个开源工具, 可以实时捕获线上HTTP请求,并在测试环境中重放这些HTTP请求,以帮助我们使用到这些产品环境数据来持续测试我们的系统。使用它之后可以大大提高我们在产品部署,配置修改或者基础架构变化时的信心。

 

NaCl (nacl.cr.yp.to) 库(读作‘Salt’)提供了关于加密,解密和数字签名的一系列的功能,使得实现安全的网络传输,或者满足其他密码学方面的需求变得简单。尽管有一些其他的工具库也能提供这些功能,NaCl 承诺提供更快的速度和更简单易用的 API。当前支持 C 和 C++ 的库,关于 Python 的封装正在进行中。

Origami (facebook.github.io/origami) 是一款免费的用户原型设计工具,其对常用功能提供了大量的快捷键操作。它为将原型设计导出为代码片段提供了可能性,支持的语言有:iOS开发上的Objective-C,Android开发上的Java,以及Web开发上的Javascript。该工具可以被用来快速构建面向用户的交互式原型和测试用户使用流程。根据从一些团队收集的使用经验来看,我们建议您在需要时对该工具进行考察。

 

Pdfmake是一个可以在浏览器里直接生成和打印PDF文档的JavaScript库。使用pdfmake,你可以创建一个支持表、列和富样式等结构元素的文档,再通过辅助方法创建并打印或者下载为不包含客户端JavaScript的PDF文件。

在我们的经验中,相比其他办法而言,通过在一开始创建大量详尽的设计图表来开发软件系统,并不是什么好的选择。但用图表来表达系统中格外复杂和难懂的部分却往往是个好的想法,何况UML本身也已经提供了若干实用的、众所周知的图表。我们喜欢用 PlantUML(plantuml.sourceforge.net)来创建这些图表,因为它让我们以清晰的文字形式来表达图表背后的意图,而不用再去摆弄那些“过度”的图形化工具。同时,文字形式的表达方式还支持版本管理,并且可以和源代码存放在一起。

SoundCloud最近开源了一个Graphite的替代品:Prometheus (prometheus.io)。SoundCloud在解决生产环境中使用Graphite所遇到的困难的过程中,开发了Prometheus,它的工作方式和Graphite不同,主要体现在其对基于HTTP的拉模型的支持上(尽管它也支持和Graphite更类似的推模型)。不仅如此,它还因为支持根据获取到的度量指标进行告警的功能而比Graphite更胜一筹,所以,在你的运维工具套件中他会变得更加活跃。尽管在生产监控领域采用新技术需要谨慎行之,但早前的报告亦显示,SoundCloud对其在生产环境使用Prometheus表示满意,而且Docker也已参与到该工具后续的开发工作中。

Quick是一个针对Swift和Objective-C的测试框架,它和用来做测试验证的Nimble捆绑发布。Quick主要用于Swift和Objective-c程序行为的验证。它和rspec和jasmine具有相同的语法风格,基础环境很容易建立。Quick良好的结构和类型断言使得测试异步程序更加容易。

 

Security Monkey 是 Netflix Simian Army 工具系统中的一员,设计这套工具的初衷是为了确保系统是以有弹性的方式构建的。它不仅提供了针对AWS设置进行可配置的潜在安全漏洞评估功能,还对正在使用的 AWS 设置的变更进行监控并及时通知相应的负责团队。早于 AWS 的 Trusted Advisor Report 和 Cloudtrail 可用之前开发出来的Security Monkey虽然提供的功能在某种程度上与他们有些重叠,但Security Monkey还提供了更多的功能。如果这些 AWS 的服务不太能够满足你的需求,Security Monkey值得一试。

 

点击这里可以下载最新中文版本PDF

Share

2015.5 技术雷达 | 语言和框架篇

2015-5 语言&框架

自从我们上一次在技术雷达中提到 Nancy (nancyfx.org) 之后,它已然成为了我们在项目上的默认选择。围绕着小而垂直切片的架构和微服务需要的仅仅是这样轻量级的部署选项和不拘小节的工具。

前端 Javascript 框架持续喷井所带来的一个好处是,时不时一个新的主意出现的时候,会引起我们的思考。React.js 是一个 UI/View 框架,在这个框架中,Javascript 函数在一个响应式的数据流中生成 HTML。我们已经见到几个小的项目成功的使用了 React.js,开发人员也被其干净的易组合的组件化方式所吸引。

Spring Boot (projects.spring.io/spring-boot) 能够让独立的基于 Spring 的应用。它非常适合启动新的微服务并且易于部署。它也通过更少的样板代码从而降低了数据访问Hibernate 映射所带来的痛苦。Spring Boot 简化了基于 Spring 的 Java 服务,这是我们所喜欢的,然而同时,我们也学会了一定要对很多依赖保持谨慎。毕竟,潜伏在表面之下的依然是 Spring。

虽然并不是所有的体验都是正面的,AngularJS 依然在 ThoughtWorks 的项目中被广泛的使用着。我们依然建议团队评估单页 Javascript 应用所带来的额外复杂度对于满足需求而言,是不是真的有必要。我们也推荐评估一些其他类似的框架,在这一版的雷达中我们提出 Ember.js,它在 ThoughtWorks 内部也逐渐变得流行。Ember 被人称道的是,它对于惯例胜于配置非常固执己见,并且有着响应迅速的核心开发团队,其性能不错并且有一套基于 ember-cli 的构建工具。

在众多 JavaScript 框架中,我们要强调 Flight.js(flightjs.github.io),Flight 是个用于构建组件的轻量级框架。它没有通过太多“神奇”的东西来为 DOM 节点添加行为。它的事件驱动和基于组件的特点,促使开发人员写出低耦合的代码。这也使得测试单个组件相对容易。然而,当组件需要彼此交互的时候还是需要格外注意。Flight.js 对测试的支持很少,并且容易卷入事件漩涡。 继承与组合,我们喜欢组合,与之类似,我们非常喜欢 Flight.js 用混入的方式处理行为。

经过一些我们在真实世界中的经验,Swift(developer.apple.com/swift)仍然表现出非常好的前景。有些问题,如过长的编译时间,已经得到了解决。然而,持续的语言的变化会导致额外的开发工作,并使得构建你自己老版本的软件非常繁琐。测试和重构也依然痛苦。总之,虽然如此,在为苹果生态圈开发新项目的时候你还是应该考虑使用 Swift。

 

点击这里可以下载最新中文版本PDF

Share