如果 Web 2.0 應(yīng)用程序使用的是基于標(biāo)準(zhǔn)的 Java Platform, Enterprise Edition 5 (Java EE) 開(kāi)發(fā)方法,那么將會(huì)面臨著嚴(yán)重的性能和可伸縮性問(wèn)題。這是因?yàn)椋罅恐С?Java EE 平臺(tái)的底層設(shè)計(jì)原理(尤其是使用同步 API 的應(yīng)用)并不適合 Web 2.0 解決方案的需求。本文將解釋 Java EE 和 Web 2.0 方法之間的不一致性,并對(duì)一些使用 Java 平臺(tái)開(kāi)發(fā)異步 Web 應(yīng)用程序的解決方案進(jìn)行評(píng)估。
很多成功的企業(yè)應(yīng)用程序都是使用 Java EE 平臺(tái)構(gòu)建的。但是,Java EE 的設(shè)計(jì)原理并不能夠有效地支持 Web 2.0 應(yīng)用程序。深入了解 Java EE 和 Web 2.0 原理之間的脫節(jié)可幫助您制定明智的決策,從而使用各種方法和工具在一定程度上解決這種脫節(jié)。本文將解答 Web 2.0 和標(biāo)準(zhǔn) Java EE 平臺(tái)緣何成為失敗的組合,并演示為何由事件驅(qū)動(dòng)的異步架構(gòu)更適合 Web 2.0 應(yīng)用程序。本文還介紹了一些框架和 API,它們通過(guò)支持異步設(shè)計(jì)使得 Java 平臺(tái)更加適合 Web 2.0。
Java EE 平臺(tái)的創(chuàng)建目的就是為企業(yè)到客戶(B2C)和企業(yè)到企業(yè)(B2B)應(yīng)用程序提供支持。企業(yè)發(fā)現(xiàn)了 Internet 的價(jià)值之后就開(kāi)始使用它增強(qiáng)與合作伙伴和客戶之間的現(xiàn)有業(yè)務(wù)流程。這些應(yīng)用程序通常要與一個(gè)現(xiàn)有企業(yè)集成系統(tǒng)(EIS)進(jìn)行交互。大多數(shù)常見(jiàn)基準(zhǔn)測(cè)試(測(cè)試 Java EE 服務(wù)器的性能和可伸縮性)— ECperf 1.1、SPECjbb2005 和 SPECjAppServer2004的用例都將這一點(diǎn)反映到了 B2C、B2B 和 EIS 中。類似地,標(biāo)準(zhǔn)的 Java PetStore 演示也是一個(gè)典型的電子商務(wù)應(yīng)用程序。
很多有關(guān) Java EE 架構(gòu)可伸縮性的明顯和暗含的設(shè)想都反映在基準(zhǔn)測(cè)試中:
- 從客戶機(jī)角度來(lái)看,請(qǐng)求吞吐量是影響性能的最重要特性。
- 事務(wù)持續(xù)時(shí)間是最重要的性能因素,并且,縮減所有個(gè)體事務(wù)的持續(xù)時(shí)間將改善應(yīng)用程序的總體性能。
- 事務(wù)之間通常都是彼此獨(dú)立的。
- 除長(zhǎng)期執(zhí)行的事務(wù)以外,只有少數(shù)業(yè)務(wù)對(duì)象會(huì)受事務(wù)影響。
- 應(yīng)用服務(wù)器的性能和部署在同一管理域的 EIS 會(huì)限制事務(wù)的持續(xù)時(shí)間。
- 通過(guò)使用連接池可以抵消一定的網(wǎng)絡(luò)通信成本(在處理本地資源時(shí)產(chǎn)生)
- 通過(guò)對(duì)網(wǎng)絡(luò)配置、硬件和軟件進(jìn)行優(yōu)化,可以縮短事務(wù)持續(xù)時(shí)間。
- 應(yīng)用程序所有者可以控制內(nèi)容和數(shù)據(jù)。在不依賴外部服務(wù)的前提下,向用戶提供內(nèi)容的最重要限制因素是帶寬。
這些設(shè)想產(chǎn)生了以下 Java EE API 構(gòu)建原理:
- 同步 API。Java EE 在很多應(yīng)用中都需要使用同步 API(重量級(jí)并且繁瑣的 Java Message Service (JMS) API 基本上是惟一的例外)。這種需求更多地源于可用性的需要,而非性能需求。同步 API 易于使用并且開(kāi)銷較低。但需要處理大型多線程時(shí),則會(huì)出現(xiàn)嚴(yán)重問(wèn)題,因此 Java EE 嚴(yán)格限制未受控制的多線程處理。
- 有限的線程池。人們很快發(fā)現(xiàn)線程是種重要的資源,并且當(dāng)線程數(shù)量超過(guò)某一界限后,應(yīng)用服務(wù)器的性能將顯著下降。然而,根據(jù)每個(gè)操作都很短暫的設(shè)想,這些操作可以分配到一組有限的線程中,從而維持較高的請(qǐng)求吞吐量。
- 有限的連接池。如果只使用一個(gè)數(shù)據(jù)庫(kù)連接,則很難獲得最優(yōu)的數(shù)據(jù)庫(kù)性能。雖然一些數(shù)據(jù)庫(kù)操作可以并行執(zhí)行,但是增加額外的數(shù)據(jù)庫(kù)連接只能將應(yīng)用程序提速到某一點(diǎn)。當(dāng)連接數(shù)達(dá)到某一值后,數(shù)據(jù)庫(kù)性能將開(kāi)始下滑。通常,數(shù)據(jù)庫(kù)連接的數(shù)量要小于 servlet 線程池中可用線程的數(shù)量。因此,連接池在創(chuàng)建時(shí)允許向服務(wù)器組件 — 例如 servlet 和 Enterprise JavaBeans (EJB) — 分配一個(gè)連接并在以后返回給連接池。如果連接不可用,組件將等待阻塞當(dāng)前線程的連接。因?yàn)槠渌M件只對(duì)連接占用很短的時(shí)間,因此這種延遲通常較短。
- 固定的資源連接。應(yīng)用程序被假設(shè)只使用很少一些外部資源。與各個(gè)資源的連接工廠通過(guò) Java Naming and Directory Interface (JNDI)(或 EJB 3.0 的依賴性注入)獲得。實(shí)際上,支持與不同 EIS 資源進(jìn)行連接的主要 Java EE API 只有企業(yè) Web 服務(wù) API。其他 API 多數(shù)都假設(shè)資源是固定的并且只有諸如用戶憑證這樣的額外數(shù)據(jù)應(yīng)該提供給開(kāi)放連接操作。
在 Web 1.0 中,這些原理玩轉(zhuǎn)得非常好。可以將一些獨(dú)特的應(yīng)用程序設(shè)計(jì)為遵守這些規(guī)則。但是,這些原理不能有效支持 Web 2.0。
Web 2.0 應(yīng)用程序具有很多獨(dú)特需求,因此,不適合將 Java EE 用于 Web 2.0 實(shí)現(xiàn)。其中一個(gè)需求就是,Web 2.0 應(yīng)用程序更多地通過(guò)服務(wù) API 使用另一個(gè) Web 2.0 應(yīng)用程序,而不是使用 Web 1.0 應(yīng)用程序。Web 2.0 應(yīng)用程序的一個(gè)更為重要的因素是,極度傾向于用戶到用戶(C2C)交互:應(yīng)用程序所有者只生成一小部分內(nèi)容;用戶負(fù)責(zé)生成大部分內(nèi)容。
在 Web 2.0 環(huán)境中,聚合應(yīng)用程序經(jīng)常使用通過(guò) SOA 服務(wù) API 公開(kāi)的服務(wù)和提要。這些應(yīng)用程序需要在 B2C 環(huán)境中使用服務(wù)。例如,一個(gè)聚合應(yīng)用程序可能從三個(gè)不同的數(shù)據(jù)源提取數(shù)據(jù),如天氣信息、交通信息和地圖。檢索這三種獨(dú)特?cái)?shù)據(jù)所需的時(shí)間延長(zhǎng)了總的請(qǐng)求處理時(shí)間。不管數(shù)據(jù)源和服務(wù) API 的數(shù)量是否增加,用戶仍然期望得到具有高反應(yīng)度的應(yīng)用程序。
諸如緩存這類技術(shù)可以緩解延遲問(wèn)題,但是不適用于所有場(chǎng)景。比如,可以緩存地圖數(shù)據(jù)來(lái)減少響應(yīng)時(shí)間,但通常并不適合將搜索查詢結(jié)果或者實(shí)時(shí)交通信息進(jìn)行緩存。
服務(wù)調(diào)用本來(lái)就是一種高延遲過(guò)程,在客戶機(jī)和服務(wù)器上通常只分配很小一部分 CPU 資源。Web 服務(wù)調(diào)用的持續(xù)時(shí)間很大一部分用于建立連接和傳輸數(shù)據(jù)。因此,通常來(lái)講,提升客戶端或服務(wù)器端的性能對(duì)于減少調(diào)用持續(xù)時(shí)間效果甚微。
Web 2.0 對(duì)用戶參與的支持引發(fā)了另外一大挑戰(zhàn),因?yàn)閼?yīng)用程序要處理來(lái)自每個(gè)活動(dòng)用戶的更多數(shù)量的請(qǐng)求。下面這些理由證明了這一點(diǎn):
- 因?yàn)榇蠖鄶?shù)事件是由其他用戶的操作引起的,因此會(huì)引發(fā)更多相關(guān)事件,并且用戶具備更強(qiáng)大的能力來(lái)生成事件。這些事件通常使用戶能夠更加積極地使用 Web 應(yīng)用程序。
- 應(yīng)用程序?yàn)橛脩籼峁┝烁嗟挠美eb 1.0 用戶僅僅可以瀏覽類別、購(gòu)買商品并跟蹤他們的訂單處理狀態(tài)。現(xiàn)在,用戶可以通過(guò)論壇、聊天、聚合等等方法與其他用戶進(jìn)行積極地交流,這將產(chǎn)生更高的通信負(fù)載。
- 如今的應(yīng)用程序越來(lái)越多地使用 Ajax 改善用戶體驗(yàn)。與普通 Web 應(yīng)用程序的頁(yè)面相比,使用 Ajax 的 Web 頁(yè)面加載要慢一些,因?yàn)轫?yè)面是由一些靜態(tài)內(nèi)容、腳本(可能會(huì)非常大)和一些發(fā)往服務(wù)器的請(qǐng)求組成。加載完成后,Ajax 頁(yè)面通常會(huì)向服務(wù)器生成一些短小的請(qǐng)求。