2012年3月ThoughtWorks技術雷達

盼盼姐發表於2012-10-18

自上期《技術雷達》釋出起,我們認為以下幾個技術趨勢越來越明顯:
● SQL 資料儲存替代產品的持續發展
● 謹慎對待從UI到測試的所有程式碼
● 基於瀏覽器的語言和技術更加嚴謹與多樣性化
● 應用程式和服務更小、更簡單、更快速

簡介

ThoughtWorks技術戰略委員會由ThoughtWorks內部的資深技術專家組成,他們經常聚在一起討論全球技術戰略和對行業有巨大影響的技術趨勢。這就促成了《技術雷達》的編制目的——幫助決策者瞭解目前能夠影響市場的新興技術和趨勢。

《技術雷達》總結了這些討論的結果,為包括從CIO到企業開發人員在內的相關人員提供有價值的資訊。本文中僅提供內容摘要,讀者可以繼續探索自己感興趣的細節。我們儘量保持雷達的簡潔明瞭,使讀者能夠快速瞭解。技術雷達用圖解的形式,將所有專案分為技術、工具、語言和平臺幾大類。有些專案會同時屬於多個類別,我們會將它歸入最合適的某個類別。另外,根據這些專案目前所處的環,用不同的階段將其進一步分組。

這些階段分為以下四個方面。

  • 保留階段(hold):應當謹慎使用的技術。
  • 評估階段(assess):值得探索的技術,以瞭解其對公司的影響。
  • 試用階段(trial):值得應用的技術。公司有必要了解如何使用該技術,並且在風險可控的專案中試用。
  • 應用階段(adopt):強烈建議公司使用的技術。公司應在適當的時候應用於專案上。

詳細介紹各類別時,我們將展示自上期《技術雷達》釋出起,每項技術的動向。新的專案或有新動向的用三角形代表,上期已經提到的專案用圓形代表。最近兩期沒有新動向的專案將不再列出,除非再有重大事件發生。

編者:

ThoughtWorks技術諮詢委員會,Rebecca Parsons(技術長),Martin Fowler(首席科學家),Nick Hines (技術長創新)等。

譯者:唱鑫,張曉蘊,史磊

技術

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
軟體行業在程式語言方面正在經歷一場復興。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等替代產品的研究可能會打破這種僵局,但該語言是否能被廣泛接受還有待時間考驗。

平臺

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-技術應謹慎使用。

相關文章