ThoughtWorks技术雷达(2012年03月)

简介

ThoughtWorks技术战略委员会由ThoughtWorks内部的资深技术专家组成,他们经常聚在一起讨论全球技术战略和对行业有巨大影响的技术趋势。这就促成了《技术雷达》的编制目的——帮助决策者了解目前能够影响市场的新兴技术和趋势。

《技术雷达》总结了这些讨论的结果,为包括从CIO到企业开发人员在内的相关人员提供有价值的信息。本文中仅提供内容摘要,读者可以继续探索自己感兴趣的细节。我们尽量保持雷达的简洁明了,使读者能够快速了解。技术雷达用图解的形式,将所有项目分为技术、工具、语言和平台几大类。有些项目会同时属于多个类别,我们会将它归入最合适的某个类别。另外,根据这些项目目前所处的环,用不同的阶段将其进一步分组。

这些阶段分为以下四个方面。

  • 保留阶段(hold):应当谨慎使用的技术。
  • 评估阶段(assess):值得探索的技术,以了解其对公司的影响。
  • 试用阶段(trial):值得应用的技术。公司有必要了解如何使用该技术,并且在风险可控的项目中试用。
  • 应用阶段(adopt):强烈建议公司使用的技术。公司应在适当的时候应用于项目上。

详细介绍各类别时,我们将展示自上期《技术雷达》发布起,每项技术的动向。新的项目或有新动向的用三角形代表,上期已经提到的项目用圆形代表。最近两期没有新动向的项目将不再列出,除非再有重大事件发生。

enter image description here
浮现式设计 (Emergent Design) 是敏捷工程实践中的一种高级实践,目前该领域上的研究十分活跃,且在不断发展。系统架构应由系统中相关技术的需求驱动产生,而不应基于对未来可能产生变化的主观推断来确定。我们已经至少识别出两种浮现式设计方法:基于精益软件原则的最后责任时刻(Last Responsible Moment)的设计,该方法适用于新建项目;而积累惯用模式(idiomatic patterns)则更适用于已有项目。

我们建议采用演进式架构(evolutionary architecture)来替代传统的预先设计出的重量级企业架构。

微服务(Micro-services)部署时通常不依赖容器(out-of-container)或者使用内嵌的HTTP服务器,这种方式摆脱了传统的大型技术服务模式。通过增加运营和维护期的复杂度换取了更高的可维护性。而运营和维护期的复杂度可以通过采用基础设施自动化和持续部署的相关技术加以降低。总的来说,微服务是管理技术债和应对扩展差异性的有效方式,尤其是部署在围绕业务能力构建的面向服务架构中时。

当十多年前内存十分昂贵时,作为在共享服务器或集群上运行和管理多个应用程序的手段,应用程序服务器技术是非常有价值的,因此深受欢迎。如今,应用程序则更多运行于独立的物理或虚拟服务器上,因此对应用程序服务器的需求大幅减少。我们建议在您的组织中评估是否停止使用应用服务器(server/application container end-of-life),而只有在该复杂技术能给你带来额外收益时再使用它。

在Java应用中嵌入诸如Jetty这样的嵌入式servlet容器( Embedding a servlet container)要比让应用运行在一个容器中有更多的好处。由于应用的启动过程更简单、开发环境更接近于生产环境,因此测试变的相对容易。因为多个应用无需共享库或驱动程序,所以不会出现库或驱动版本不匹配等令人讨厌的问题。虽然采用这种模型需要在生产环境下同时管理和监控多个Java虚拟机,但这种模型的简单性和隔离性所带来的优势更为显著。

随着嵌入式HTTP服务器越来越受欢迎,脱离容器的功能测试(out-of-container functional testing)也越来越普及。 通过采用模拟容器,你可以在系统的边界上构建测试,这样既可以实现快速反馈,又能获得较高的测试覆盖率。诸如Jetty等服务器和.NET平台上的Plasma工具可以大大降低运行测试集所需的时间。

体验式设计(Experience Design - XD)是敏捷理念为适应现实世界的约束而演进的方式之一。我们一直在寻找创新方法,以便将传统的预先设计与持续交付(Continuous Delivery)等实践相结合。体验式设计是一个比较成熟的研究领域。

目前有一个令人担忧的趋势,那就是开发人员与运行代码的硬件越来越远。开发和维护之间日益增长的虚拟化和分离使这种情况变得更糟。与之形成鲜明对比的是某些团队正在编写可以获得机械同情(mechanical sympathy)的代码,这种代码可以使软件获得难以想象的性能提高。例如Java平台上的LMAX Disruptor开源项目就是一个例子。对于金融和大数据等对性能有很高要求的领域,越贴近底层就越能获得更高的回报。

将敏捷方法应用于数据仓库、商业智能和敏捷分析(Agile Analytics),可以获得更好的回报,并且可以提高商业响应速度。与传统的批量更新相比,通过采用轻量级的技术,如REST服务等来实现,几乎可以达到实时地更新数据。这样可以从应用中获取用户的行为数据,以支持更好的用户体验和数据可视化效果。

我们发现在应用中添加简单的健康检查页面(Health Check Pages)非常有用。这样人们可以快速了解单个节点的健康状况。我们经常对其进行扩展并添加如订单号、错误率或类似的度量信息。使用简单的嵌入式web服务器,甚至可以让非web的服务也很容易的通过HTTP暴露内部的信息。通过使用微格式,这些网页可以很容易的被其他监控工具所使用,从而成为全面监控系统的一部分。

持续交付过程的一个关键点是要具备基于业务需要可任意发布软件的能力。一键式部署(Single Command Deploy)的能力取决于将持续交付下的一系列活动,包括从构建、测试到脚本化环境搭建和部署的自动化。我们发现,以持续交付为目标,会将自动化和测试的先决条件推向您公司内的其他上游部门。

持续交付技术正在缩短软件交付的“最后一英里”,从而允许更频繁地发布新功能。生产环境免疫系统(Production Immune System)可以追踪进入到生产环境中的这些变更,当变更对系统的关键度量指标,比如利润,产生不良影响时能够自动回滚变更。成功执行这种对系统影响很大的回滚需要依赖可靠的度量指标,以及自动化的A/B部署。

自动化是持续交付的核心实践。当公司在自动化管理基础设施和环境方面做得越来越好的同时,开发环境基础设施的自动化(Infrastructure Automation of development workstations)却常常被遗忘。由于避免了人工搭建特定环境,这种方法大大提高了生产率,并可实现同一环境的无缝复制。至于环境的其它部分,一般情况下使用平台包和语言构建工具就足够了,也可根据需求来使用Puppet 或Chef等工具 。

PowerShell等成熟的工具,搭配使用Chef和Puppet等新工具,是驱使我们本期《技术雷达》重点介绍Windows环境自动化(Windows Infrastructure Automation)的主要因素。使用鼠标和菜单选项手动配置环境太慢,而且在错误配置时易导致机器处于未知不可用状态。我们建议使用命令行工具来确保配置过程可脚本化,从而更加清晰。

我们一向提倡使用静态和动态代码分析工具来帮助我们收集代码库信息。由于持续交付运动使软件开发的重点拓宽,开发和运维过程中的数据可视化(Data Visualizations of development and operations),高效且有目的性的程序分析(profiling)和监测也应成为公司技术栈的一部分。

用户故事级别的测试会导致将重点放在完成单个故事,而不是耦合的功能上。这样往往会导致开发出一组过于庞大、运行缓慢且难以维护的测试套件,从而导致反馈时间的延长。针对此的一个可选方案是使用用户旅程(User Journey),即将用户故事分组然后抽象出用户交互行为,从而为用户和业务双方提供价值。将用户旅程作为自动化的测试套件,可以在相对长的时间内和用户需求匹配,这类测试如果失败,则表明应用程序不能满足用户的需求。

一些行为驱动设计(BDD)的测试框架,比如Cucumber,与浏览器端自动化测试框架的组合,比如Selenium等,使得浏览器级别的验收测试被广泛使用。这样做的一个缺点就是增加了大量运行成本很高的测试。相反,我们应该在合适的粒度去进行测试(Test at the Appropriate Level),尽可能的贴近代码本身,这样才能最大程度上提高测试运行的效率。浏览器级别的测试应该处于金字塔塔尖的位置,下面应该是相应层的验收测试与单元测试。

虽然单元测试和功能测试被广泛用于标准的开发实践中,但这种趋势并没有延续到性能测试领域中。目前,常用的测试工具会让测试人员创建出不可重用代码或陷入录制脚本(click-and-script)的思维方式。将性能测试作为头等公民来对待(performance testing as a first class citizen),可以让我们产生出更高质量的测试,覆盖更多的功能点。还有助于创建更好的工具来运行性能测试,以及产生出易于维护和可测试的测试套件。

测试录制工具(Test Recorder)看似很有价值,因为它们提供了一种快速捕获录制用户对应用程序操作的方式。然而我们反对将测试录制工具作为一种常用工具,因为录制的测试往往非常脆弱,会因为UI的轻微变化而导致失败。测试录制工具产生的测试代码质量往往相对较差,经常出现不必要的重复。更重要的是,测试录制工具会阻碍测试自动化团队和开发团队之间的沟通。当面对一个很难通过用户界面进行测试的应用时,团队之间进行一次重要的谈话从而构建一个更容易测试的UI才是一个合理的解决方案。

enter image description here
混合持久化(Polyglot persistence)是指根据效率和数据使用方式的差异而使用不同的数据存储方式的技术。不是所有的应用场景都适合使用RDBMS做为默认的数据库。相反,先问这样的问题: session相关数据是否应该保存在这个数据库中?还是应该保存在某个Key-Value存储系统中?客户和产品的关系数据是否应该保存于图形数据库中?即使是在一个应用程序内,使用如MongoDB,Riak或Neo4J等NoSQL数据库,也会让我们重新考虑如何管理数据。

Riak是一个无模式(schemaless)、无数据类型的分布式Key-Value存储系统。它在写入诸如session、购物车、日志流等大数据时很有优势。它的分布式簇的自我恢复、簇间分布数据的一致性保证、冲突检测并自动修复等功能,在需要高可用性的环境下会非常有用,并且可以为架构设计提供有趣的解决方案。

随着移动应用的兴起,JavaScript的文件大小和性能变得尤为重要。作为对一些大库的直接回应,JavaScript微框架(Javascript micro frameworks)出现了。这些轻量级的框架只做一件事情,比如DOM操作或MVC,并且大小在1KB内。通过一些微框架的组合使用,开发人员就可以获得他们想要的所有功能,并且不需要大库的开销。Microjs.com里有大量这样的微框架,当然也有工具可以将这些微框架捆绑成一个单独的库。

JavaScript现在已经被认为是一种功能强大的主流语言,可以在多种客户端和服务器环境下使用。随着JavaScript代码库的不断扩展,需要有更多JavaScript工具(Javascript Tooling)的支持,尤其是在持续集成和测试领域。来自于不断成长且充满活力的社区的Backbone.js,SpineJS,JavaScriptMVC,Jasmine,JSTestDriver和 HRcov等工具正在向前端发展 。

Frank是一个开源库,可以使用Cucumber编写iPhone和iPad的功能测试,并在远程设备上执行。以前在iOS上,验收测试驱动的开发非常麻烦,该库填补了一项重要的空白。

虽然过去几年中MVC一直是web开发的主流模式,但大多数库和框架未能遵守其最重要的原则之一:保证View层无逻辑。如果不能保证View层没有逻辑(logic-free markup),会增加应用程序复杂性,使其难于测试,代码无法重用。最近出现的一些DSL,如Mustache开始扭转这种局面,它们适用于多种语言和平台,并且允许使用任意工具编辑,无需额外的语言支持,对UI开发和应用程序的总体设计很有帮助。

我们将继续强调基础设施即代码(infrastructure as code)。该技术将基础设施配置与代码同等对待,将配置信息提交到源代码管理系统,然后将更改谨慎地应用到数据中心。

使用原生操作系统包部署组件及其依赖有许多优点,然而,使用工具创建Linux原生包的过程却比较繁琐。FPM则是一个有用的工具,可以轻松创建RPM,DEB或Solaris包,减少了很多麻烦。

包管理系统是一种被广泛采用的实践方法,用于整合第三方类库。像RubyGems,Maven,APT等工具在语言和系统层面均可支持。NuGet是.NET平台上的包管理系统:它由一个Visual Studio IDE 扩展和一个PowerShell模块组成,为进一步实现在.NET平台上的自动化构建提供了可能。

PSake(“sake”的发音类似于日语米酒的发音)是用PowerShell实现的自动化构建工具。PSake提供了简明的语法来声明构建任务和依赖,而不使用XML。并且您还可以在自己的构建脚本内使用PowerShell和.NET框架的所有功能。

Maven一直是Java领域自动化构建的主打产品。然而,由于其缺少灵活性和自动化最佳实践的支持,尤其是在持续交付领域,应考虑使用Gradle替代Maven。

enter image description here
Node.js只是越来越受欢迎的异步I/O单线程服务器(single threaded servers with asynchronous I/O)的一个例子。传统的web或应用服务器为每个访问请求创建一个线程,当与该访问请求相关联的所有处理任务都完成且收到响应之后才释放资源。如果其中任意一个处理任务需要占用I/O,则在I/O发生时线程会被阻塞。这种方法导致每个连接都会占用一个线程,而不管该线程实际是否消耗CPU周期,所以会浪费如文件描述符和内存等资源。现今开始出现一种新的服务器架构,它使用单线程来服务多个连接,可以异步处理I/O。这种架构已经出现在如下平台上:Node.js (运行在Google V8上的JavaScript服务器),Nginx(开源的Web和代理服务器),以及Webbit(Java应用服务器)。这些服务器因为处理每个连接所占用的资源非常少,所以处理并发连接的能力比传统的web服务器要高上很多量级。

出于对隐私和安全的担心,或是为了赋予已投资的硬件新的用途,许多公司开始选择建立自己的私有云(Private Cloud)。针对此市场有多种开源产品以及商业产品。但计算、存储和网络管理仅仅是应用私有云的起点。私有云中许多服务和流程必须要定制实施,这样才足以和外部Amazon, Rackspace或者其他开放云平台提供的公有云服务进行竞争。

混合云(Hybrid clouds)描述了集成公有云和私有数据中心最佳特性的一组模式。混合云允许应用程序在正常时间运行于私有数据中心,而高峰时段的过载请求则运行于公有云中的租赁空间。另一种集成公有云和私有云的敏捷的方法是利用公有云的灵活性和延展性来开发和了解应用的生产环境特性,然后在其稳定时移入私有数据中心的永久架构内。

虽然用户很容易忽略基于云服务的地理位置,但在考虑选择合适的平台时,因为法律或者技术方面的原因,地理位置反而是一个严重的制约因素。随着Amazon最近加入了巴西和新加坡区域,对于以前处于IaaS服务不太好的地区的人们来说,基于AWS的系统将变得更加切实可行。此外,Amazon持续的为已有的服务添加新的特性,比如VPC,因此在对资源初始化的灵活性要求很高的场景下,我们仍然推荐使用AWS

AppHarbor为.NET平台提供了PaaS(平台即服务)选择。它遵循了由Heroku开创的价格模型和架构。AppHarbor是.NET应用部署的很有前景的一种方式,它抽象了与平台相关的最基本的配置要求。AppHarbor正在迅速成熟,我们预期在不久的将来它会吸引更多人的注意。

虚拟容器做为一种虚拟化的方式,对SaaS和PaaS十分有吸引力。像OpenVZ这样的Linux容器(Linux Containers),提供了隔离和管理虚拟机的便利,而省去了一般虚拟化带来的管理成本。在容器模型中,子操作系统受限于主操作系统,需保持和主操作系统一致,对于许多云应用来说,这种限制不是大问题。

我们发现许多企业都开始建立他们自己的内部云部署环境,这些环境在搭建开发和测试环境时很容易被复制。很多情况下,创建环境的过程可以实现自动化,只需一个按键,开发人员就可以创建一组可以运行企业核心业务和协作系统的主机。从某种意义上讲,这是为内部客户提供的特定领域的PaaS(Domain-specific PaaS)。

Windows Phone 7令人惊讶地挺过了Windows平台长时间的危机。经过多次失败尝试后,微软不仅生产出用户体验与行业内其他主要竞争者相当的手机操作系统,而且还提供了配套的开发支持。微软正在使Windows Phone 7成为一个强有力的竞争者,以及成为企业竞技场上整合体验更好的另一个选择。然而是否能够影响用户的选择还有待观察。

OpenSocial定义了一组规范,为不完全受信任的应用程序共享信息提供了标准方式。虽然OpenSocial起初是为面向公众的社交网站提出的,但它在企业防火墙之内却可能有更大的潜力,因为用标准的方式共享应用程序之间的数据和内容经常比满足标准和安全的需求更有价值。

敏捷软件开发中的一个重要的机制是反馈回路。我们观察到的一个共同的且代价昂贵的反馈环路断路是硬件和软件负责人之间沟通(communication between those responsible for hardware and software)缺失,最终造成了不必要的损失。您必须全面考虑总体架构,从单一角度考虑硬件或软件都是不充分的。

随着虚拟化的不断发展,有些公司将虚拟机当成物理设备(treating virtual machines like physical infrastructure)。我们不赞成为每个虚拟机都安装全套的操作系统或使用虚拟机进行负载测试。虚拟机可以被克隆、快照和操作,这些都是实际机器做不到的。虚拟机也有与实际机器硬件非常不同的性能特点。使用虚拟机时应全面了解其优点和局限性,否则您真的会遇到麻烦。

许多团队会遇到一些问题,这些问题是因为测试环境缺少一个只在生产环境中才具备的昂贵的硬件组件。而在许多情况下,预生产环境并不能达到生产环境的规模,因为不具备生产环境下的所有组件。如果您只能购买的起一个解决方案(buying solutions you can only afford one of),如SAN, 防火墙或负载平衡器,那我们建议您不要购买这样的解决方案,因为这会导致只能在生产环境中进行实际测试,而其它环境都不具备这样的能力。

长期以来,我们一直对Flash和Silverlight等RIA技术不太热情,因为潜在的供应商封锁,对敏捷工程实践的支持不到位,以及潜在的过度使用等问题。现在看起来大厂商也开始同意我们了。因为较新版本的HTML可以处理大多数以前需要RIA才能解决的常见问题。我们认为新项目在使用任何这样的技术之前必须理由充分,并审慎地进行战略考虑。

目前市面上有大量的企业软件包,声称可采用零编码提供灵活的功能。这当然是一个有吸引力的概念——非技术的商业用户可以根据业务的独特要求配置软件,而不需要学习编程语言或雇用专业软件开发人员。但是应当牢记,影响生产环境中软件行为的任何变化,无论是编码、配置、数据还是环境,都会导致业务系统缺陷或故障。编码只是专业软件生产周期中的一步,系统修改不论是通过拖拽界面还是高级编程语言来实现,反复地分析、测试、构建和部署还是必须的,并不会因此而消失。在评估一个零代码定制软件包 (zero-code package) 时,要确保产品支持这些过程,并具有实施零代码定制软件包所需的IT支持。

基于简单的网络即平台的技术,例如REST,OAuth所取得的进展和大家的接受程度以及WS-已知问题,我们重申我们的观点:WS-技术应谨慎使用。

enter image description here
软件行业在编程语言方面正在经历一场复兴。ThoughtWorks认为现在是时候评估哪些语言对您的公司更有帮助,同时评估所做出选择的有效期限。您需要关注语言(care about languages)。有独立支持团队的传统结构化的组织可能会发现技术限制了选择,此时,DevOps提供了一个途径。

函数式编程的发展依然较为缓慢,但其在开发人员心中的地位和代码库却在稳步上升。Scala,Clojure,F#等新语言提供了许多新功能。现在Functional Java,TotallyLazy 和 LambdaJ 等库将某些函数式语言的特性,尤其是一些高阶函数的特性和集合操作,移植回了Java。我们喜欢这种趋势,因为它展现出了未来语言的常见功能,并且还允许开发人员在自己熟悉的语言中使用这些新特性。

微软F#不断发展,最近发布了F# 3.0 beta。F#十分擅长清晰地表达业务逻辑和领域逻辑。想要在程序中清晰表达业务逻辑的开发人员,可以选择使用F#,而其它主要管道代码(plumbing code)使用C#。

ClojureScript仅仅展示了Clojure核心的跨平台功能,它将Clojure的主要部分移植到了JavaScript上来运行,抛弃了一些Clojure在JVM和CLR上的独特功能,比如软件事务存储,但ClojureScript更高级的复杂功能却具有令人惊讶的高保真度。ClojureScript提供的一个有趣的功能是可以使用ClojureScript将含有JSON格式的数据结构以原有的形式发送出去。这是因为Clojure是一种Lisp语言,也就意味着您也可以发送“真正”的代码。

将丰富的用户体验通过网络传送到桌面、平板电脑和手机设备主要依赖于JavaScript,我们继续推荐在您的应用将JavaScript作为“一等公民” 语言(JavaScript as a “first class” language)。开发人员应认真考虑如何采用与其他编程语言同样严格的标准来构建,测试,重构和维护JavaScript代码。

由于JavaScript语言本身的缺陷及其内在的性能问题,Google发明了Dart语言用来取代JavaScript。Dart与之前Google发明的语言一样,其语法和语义与Java类似,想要比JavaScript原型特性更具吸引力。浏览器开发社区对Dart的接受程度仍然比较低,这也是可以理解的,Chrome的持续发展和CoffeeScript等替代产品的研究可能会打破这种僵局,但该语言是否能被广泛接受还有待时间考验。





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值