在 Web 服務(wù)中至少有三個(gè)因素(或缺少這些因素)與性能有直接關(guān)系:
Web 服務(wù)給日益復(fù)雜的功能提供了一個(gè)公共接口。雖然沒有一個(gè)針對(duì)底層服務(wù)的規(guī)范,但是基本的概念是您編寫代碼位并將它們部署到網(wǎng)絡(luò)中。您可以通過多種傳輸利用這個(gè)功能,最普通的是 HTTP。Web 服務(wù)的無效率就在這里:許多傳輸不是以性能為中心的,并且 XML 的包裝和解析給予了直接過程調(diào)用無法承擔(dān)的開銷。但是,正如阿爾伯特・愛因斯坦(Albert Einstein)曾說過的,時(shí)間是相對(duì)的。
在因特網(wǎng)的世界中,多數(shù)人按照秒來思考時(shí)間。多數(shù) Web 站點(diǎn)都在力爭比六秒更快的響應(yīng)時(shí)間??紤]一下您可以使用 Web 服務(wù)調(diào)用來構(gòu)建一個(gè) Web 站點(diǎn)(如新聞門戶網(wǎng)站),那么 Web 服務(wù)的性能甚至需要更快。這是一個(gè)挑戰(zhàn)。其目標(biāo)是使半?yún)⑴c的 Web 服務(wù)的響應(yīng)時(shí)間大約為三秒。您可以通過查看您已經(jīng)控制的 Web 服務(wù)部分(具有特殊功效的代碼位)來達(dá)到這個(gè)目標(biāo)。
![]() |
|
如今的 Web 高速緩存系統(tǒng)利用一些指向內(nèi)容片段的唯一的標(biāo)識(shí)符。他們利用底層的協(xié)議來跟蹤數(shù)據(jù)位(如 HTML 文檔或圖像)的及時(shí)性。雖然 HTTP 傳輸上的 Web 服務(wù)有端點(diǎn)(URL),但是使其唯一的簡單對(duì)象訪問協(xié)議(Simple Object Access Protocol(SOAP))信封(envelope)部分是 SOAP 信封中的參數(shù)值,如 清單 1 所示。由于 SOAP 是 XML,幾個(gè)標(biāo)記可能有許多不同的標(biāo)簽但仍然標(biāo)注同一個(gè)數(shù)據(jù)。作為一個(gè)整體,您可以創(chuàng)建一個(gè)與下一個(gè) SOAP 信封不同的 SOAP 信封并同時(shí)使它們恰好代表同一個(gè)數(shù)據(jù)。此外,如果您決定在一個(gè) SOAP 信封單獨(dú)的、唯一的部分的基礎(chǔ)上進(jìn)行高速緩存,那么沒什么辦法來表明這個(gè)查詢是否適于這種高速緩存。
開發(fā)人員為特定類型的情況和數(shù)據(jù)調(diào)整當(dāng)前的商業(yè) Web 高速緩存解決方案。而且,即使有解決方案存在,它可能也沒有將開發(fā)人員所要求的操作考慮在內(nèi)。雖然有現(xiàn)成的商業(yè)工具可以使用,但是運(yùn)行您自己的高速緩存對(duì)象則提供了最好的靈活性、最強(qiáng)的控制和最大的購買能力。
![]() |
|
多數(shù)進(jìn)程都涉及到了計(jì)算。計(jì)算可以是一個(gè)等式或者是能產(chǎn)生一個(gè)新值的網(wǎng)絡(luò)交易。不管計(jì)算是什么,您都應(yīng)該標(biāo)識(shí)出浪費(fèi)時(shí)間的進(jìn)程部分。考慮一下報(bào)告原子時(shí)間(atomic time)的進(jìn)程吧。如果這個(gè)進(jìn)程需要一個(gè)到政府服務(wù)部門的簡單網(wǎng)絡(luò)時(shí)間協(xié)議(Simple Network Time Protocol(SNTP))連接,那么更加頻繁地計(jì)算比每幾秒鐘計(jì)算一次浪費(fèi)時(shí)間。完成一個(gè)到原子時(shí)間服務(wù)的連接所需的時(shí)間會(huì)影響時(shí)間讀取的精確性。對(duì)于這個(gè)示例來說,假設(shè)您僅保持十秒的精度。獲得當(dāng)前時(shí)間的網(wǎng)絡(luò)調(diào)用是高速緩存的一個(gè)完美項(xiàng),因?yàn)槟?10 秒約束意味著數(shù)據(jù)在至多 10 秒鐘之內(nèi)不會(huì)更改。您僅僅需要大約每 8 秒進(jìn)行一次新的連接,以嘗試對(duì)網(wǎng)絡(luò)等待時(shí)間進(jìn)行補(bǔ)償。
這種樣式的高速緩存是簡單的。涉及到兩個(gè)靜態(tài)變量:您上次檢查時(shí)間的時(shí)間以及時(shí)間本身。您上一次檢查的時(shí)間作為觸發(fā)刷新來自時(shí)間服務(wù)器(timeserver)的時(shí)間的變量。這個(gè)時(shí)間需要在存儲(chǔ)時(shí)間過期的任何時(shí)刻時(shí)被刷新。這是在上一次檢查的時(shí)間戳記基礎(chǔ)上被檢查的。顯然,如果客戶機(jī)對(duì)時(shí)間的請(qǐng)求在所存儲(chǔ)的時(shí)間過期前進(jìn)入,您會(huì)返回到已被高速緩存的時(shí)間。
您還可以為文本轉(zhuǎn)化為語言(text-to-speech)服務(wù)生成并高速緩存音頻文件。生成大量數(shù)據(jù)以代表一個(gè)音頻文件需要耗費(fèi)許多資源。這個(gè)服務(wù)接收字符串并將音頻文件作為一個(gè)附件返回。您可以存儲(chǔ)這個(gè)動(dòng)態(tài)生成的音頻并將文本表示存儲(chǔ)為密鑰。
這夠簡單的了,但是請(qǐng)考慮一下:您將這些已高速緩存的項(xiàng)保存多久以及其他客戶機(jī)將多久調(diào)用一次這個(gè) Web 服務(wù)?
第一個(gè)問題訴諸了這樣一個(gè)事實(shí):每一個(gè)系統(tǒng)的資源都是有限的。將 100 MB 的音頻數(shù)據(jù)存儲(chǔ)在內(nèi)存中可能使存儲(chǔ)量過大。您可以設(shè)計(jì)一個(gè)高速緩存來擁有一個(gè)最大的存儲(chǔ)量。它可以將用得最多的條目保存,同時(shí)又將最陳舊的和最少用到的條目清除。您可以決定這個(gè)高速緩存沒有時(shí)間限制。
第二個(gè)問題突出顯示了服務(wù)可能被其他客戶機(jī)很少使用,以至于對(duì)任何事物進(jìn)行高速緩存都沒有用處。例如,假設(shè)一個(gè)想像的 Web 服務(wù)的總交易時(shí)間為兩秒。如果對(duì)這個(gè) Web 服務(wù)的調(diào)用不多(每分鐘少于一個(gè)),那么可以確定沒有必要進(jìn)行高速緩存。然而,如果負(fù)載是每秒 100 個(gè)調(diào)用,那么可能有正當(dāng)?shù)睦碛蛇M(jìn)行高速緩存。一個(gè)變通方法是使用一個(gè)能在需要時(shí)存儲(chǔ)條目而在過了有效期后清除條目的自清除高速緩存(self-pruning cache)。清除高速緩存對(duì)象減少了它的內(nèi)存量。高速緩存能夠依靠實(shí)現(xiàn)將常常被高速緩存的對(duì)象保存,時(shí)間長于不常使用的被高速緩存的對(duì)象。
高速緩存的設(shè)計(jì)常常以其將得到使用的環(huán)境為基礎(chǔ)。本文既包括了簡單的示例,也包括了復(fù)雜的示例。本文還考慮到了以下內(nèi)容:
![]() |
|
高速緩存在任意應(yīng)用程序中都會(huì)是一個(gè)有用的工具。在 Web 服務(wù)中,您可以更加頻繁地使用高速緩存,因?yàn)閼?yīng)用程序的本質(zhì)在許多情況下是重復(fù)的和高負(fù)荷的查詢。有時(shí)您在代碼中插入一個(gè)高速緩存解決方案是合適的。在其他情況下,當(dāng)您可以將一個(gè) Web 服務(wù)調(diào)用的全部結(jié)果高速緩存時(shí),在該 Web 服務(wù)被調(diào)用之前就插入高速緩存檢查會(huì)比較好。為了演示這后一種方法,假設(shè)您正在使用 Apache 的 Axis 中的 Java(TM) 開發(fā)環(huán)境和 Web 應(yīng)用程序服務(wù)器(如 IBM WebSphere)。(請(qǐng)注意您在這種類型的環(huán)境中需要做的每一樣工作都在用于 Web 服務(wù)的 IBM WebSphere SDK 中有所提供。)這個(gè)練習(xí)的目標(biāo)是將高速緩存與實(shí)際的 Web 服務(wù)代碼分離開來。
Apache 的第一個(gè) SOAP 實(shí)現(xiàn)取決于提供程序的概念。這個(gè)代碼位將 SOAP 信封的對(duì)象和方法進(jìn)行解碼,實(shí)例化本地對(duì)象,并返回將會(huì)在返回 SOAP 信封中被包裝起來的結(jié)果。Axis 有一個(gè)與提供程序功能相當(dāng)?shù)牟糠?,不過它通常被稱為軸心點(diǎn)(pivot point)。這是因?yàn)?Axis 提供了您可以用來定義交易流的體系結(jié)構(gòu)。您通過處理程序定義流。每一個(gè)處理程序都可以對(duì)當(dāng)前傳入的和傳出的 SOAP 信封進(jìn)行操作。處理程序提供了將方法和服務(wù)作為一個(gè)大一些的服務(wù)的流的一部分執(zhí)行的能力,如 圖 1 所示。軸心點(diǎn)恰恰是另一個(gè)處理程序,但是它暗示了請(qǐng)求成為響應(yīng)的點(diǎn)。這個(gè)軸心點(diǎn)是一個(gè)您可以插入高速緩存的地方。
本示例應(yīng)用程序的高速緩存是一個(gè)通用的解決方案。您將把對(duì)象設(shè)計(jì)為一個(gè)單子實(shí)例(singleton)(這個(gè)設(shè)計(jì)模式將把這個(gè)對(duì)象限制在一個(gè)單個(gè)實(shí)例中)并使用合適的檢索和存儲(chǔ)方法對(duì)高速緩存進(jìn)行操作。高速緩存將這些對(duì)象存儲(chǔ)一個(gè)固定時(shí)間并將旋轉(zhuǎn)一個(gè)線程來在需要時(shí)清除這些項(xiàng),如 圖 2 所示。對(duì)于什么可以被高速緩存這個(gè)問題只有一個(gè)限制 ― 這個(gè)項(xiàng)必須是一個(gè)對(duì)象。
因?yàn)樵S多 Apache 項(xiàng)目具有開放源代碼性質(zhì),因此您可以為 Axis SOAP 實(shí)現(xiàn)下載源代碼。(在撰寫本文時(shí)它仍是測試版,但是它最終會(huì)是一個(gè)受歡迎的針對(duì) Java Web 服務(wù)工作的解決方案。)您將修改 RPCProvider 類(org.apache.axis.providers.java.RPCProvider.java)。許多提供程序都支持多種傳輸。雖然您可以編寫自己的類,但是您可以采用簡單的途徑,利用 Axis 開發(fā)人員已經(jīng)做的所有艱辛勞動(dòng)。您完全可以拷貝由 Apache 員工開發(fā)的 RPCProvider 并添加一些代碼來以一個(gè) RPCCachingProvider 結(jié)束。為了高速緩存一個(gè)來自 Web 服務(wù)的響應(yīng),您需要生成一個(gè)用來對(duì)它進(jìn)行索引的唯一的密鑰。在將被調(diào)用的對(duì)象和 SOAP 信封中的變?cè)幕A(chǔ)上(如 清單 1 所示),您可以生成這樣一個(gè)密鑰。具體說來,您需要確定服務(wù)、方法和變?cè)?
|
請(qǐng)注意這個(gè)高速緩存提供程序假定變?cè)形ㄒ坏淖址硎?,但不是每一個(gè)調(diào)用都有唯一的字符串表示。例如,當(dāng)一個(gè)字節(jié)數(shù)組作為字符串被檢索時(shí),它將看起來有些像 [B@4f25045a。每一個(gè)字節(jié)數(shù)組看起來都是不同的,高速緩存將假定每一個(gè)數(shù)組都是唯一的,這導(dǎo)致了高速緩存沒有有效工作。雖然有許多解決這個(gè)問題的方法,但是本文使密鑰生成簡單。一旦您有了一個(gè)唯一的密鑰,請(qǐng)檢查一下看看在高速緩存中是否有這個(gè)項(xiàng)。如果有這個(gè)項(xiàng),那么就返回已存儲(chǔ)的響應(yīng)。在這種情況下,您可以在高速緩存一個(gè) Web 服務(wù)調(diào)用產(chǎn)生的響應(yīng)的地方高速緩存 SOAP 體,如 清單 2中的 soapenv:Body 標(biāo)記描述的那樣。您可以決定更新高速緩存項(xiàng)的時(shí)間來使其時(shí)間更久些。但是,如果高速緩存沒有一個(gè)匹配的項(xiàng),您應(yīng)當(dāng)繼續(xù)執(zhí)行這個(gè)調(diào)用并存儲(chǔ)所產(chǎn)生的響應(yīng)片段。您可以指定所高速緩存的項(xiàng)目每次保留 30 秒,并在每次被請(qǐng)求時(shí)刷新,如 清單 3所示。
|
|
在軸心點(diǎn)實(shí)現(xiàn)高速緩存系統(tǒng)將其與服務(wù)代碼分離開來。奇妙之處在于服務(wù)的部署。不要標(biāo)識(shí)缺省的提供程序(java:RPC),而是將軸心點(diǎn)指定為處理程序并向指向您的新的高速緩存提供程序的服務(wù)添加一個(gè)參數(shù),如 清單 4 所示。這個(gè)體系結(jié)構(gòu)讓您在部署時(shí)決定是否使用高速緩存。您甚至還可以用一個(gè)服務(wù)參數(shù)為高速緩存項(xiàng)具體化生存時(shí)間。Axis 提供了所有的這個(gè)功能和靈活性。您可以在舊的 Apache SOAP 實(shí)現(xiàn)中完成同一個(gè)提供程序概念,但是為了訪問方法和參數(shù)值,您要多做一點(diǎn)兒工作。
|
![]() |
|
既然您已經(jīng)探索了高速緩存系統(tǒng)并且創(chuàng)建了一個(gè)通用的高速緩存對(duì)象,您可以學(xué)習(xí)如何在其他的 Web 服務(wù)解決方案中集成高速緩存了。雖然您是在流方案中實(shí)現(xiàn)這個(gè)通用的高速緩存對(duì)象,但是您也可以在其他場合使用它。如果不將代碼用于工作中,那么即使有它們也沒用。
![]() |
|
這第一個(gè)示例研究了在訪問 Web 服務(wù)之前需要進(jìn)行認(rèn)證以幫助限制訪問和跟蹤使用情況的需求。有時(shí)您需要檢查一個(gè)用戶連接到公司 LDAP 目錄或數(shù)據(jù)庫的認(rèn)證憑證,對(duì)此進(jìn)行高速緩存的操作就是這樣的事務(wù)。
這個(gè)示例使用了一個(gè)固定大小的高速緩存,如 1 MB 的存儲(chǔ)器或 100 個(gè)高速緩存項(xiàng)。它使用用戶標(biāo)識(shí)作為密鑰,其值為作為 MD5 散列存儲(chǔ)的密碼。這確保了安全并同時(shí)仍能可以根據(jù)所高速緩存項(xiàng)而驗(yàn)證未來的密碼。如果認(rèn)證失敗,您可以除去這個(gè)標(biāo)識(shí)。最后,為了安全起見,請(qǐng)考慮一下將高速緩存超時(shí),因?yàn)槊艽a更改和標(biāo)識(shí)會(huì)被取消。
第一次您檢查用戶的憑證時(shí),在成功登錄時(shí)請(qǐng)將它們存儲(chǔ)在高速緩存中。如果憑證經(jīng)證明是無效的,那么便會(huì)返回錯(cuò)誤。對(duì)這個(gè)服務(wù)的后繼調(diào)用可以獲得密碼認(rèn)證的安全性,而實(shí)際上不一定會(huì)導(dǎo)致數(shù)據(jù)庫連接或公司 LDAP 目錄查找的開銷。雖然這看起來可能并沒有節(jié)省多少開銷,但如果時(shí)間很長而且負(fù)載很大時(shí),這樣就能夠節(jié)省不少的開銷。
![]() |
|
有時(shí),您可能發(fā)現(xiàn)您的 Web 服務(wù)是個(gè)精巧的系統(tǒng)中的一部分。在這第二個(gè)示例中,系統(tǒng)需要一臺(tái)客戶機(jī)來首先獲得一個(gè)已被認(rèn)證的令牌并將這個(gè)令牌給后繼服務(wù)。為了進(jìn)一步加強(qiáng)系統(tǒng)的安全,令牌只能被使用一次。使 Web 服務(wù)能夠處理哪些令牌先前已經(jīng)使用過就可以實(shí)施這個(gè)只用一次模型(use once model)。它使令牌避免了惡意提交以在一個(gè)資源被使用一次后獲得對(duì)它的訪問。這個(gè)方案利用了一些在 Axis 安全性演示和 IBM Web Services ToolKit 早期版本中的數(shù)字簽名的概念。在那些示例中,數(shù)字簽名在 SOAP 信封的基礎(chǔ)上被創(chuàng)建。可以應(yīng)用同樣的驗(yàn)證測試。
例如,您可以生成一個(gè)特別的有時(shí)間戳的認(rèn)證令牌(這個(gè)令牌已被數(shù)字簽名以防止在傳輸過程中篡改)。在訪問第二個(gè)服務(wù)時(shí),您可以驗(yàn)證第一個(gè)服務(wù)是始發(fā)者(originator)且這個(gè)令牌具有完整性。這提供了一個(gè)使許多 Web 服務(wù)解決方案安全的方法;一個(gè)對(duì)象級(jí)別的高速緩存能使您迅速且簡單地完成。
在這個(gè)實(shí)例中,高速緩存系統(tǒng)是自清除種類的。您僅需要一個(gè)通過其密鑰存儲(chǔ)項(xiàng)的方法。您可以將生存時(shí)間設(shè)置為比原先的令牌請(qǐng)求時(shí)間的有效期長。這個(gè)高速緩存便是自清除的,因此您維護(hù)了健康的資源使用。
當(dāng)接收到一個(gè)請(qǐng)求時(shí),您可以檢查這個(gè)項(xiàng)是不是不在高速緩存中。如果它在高速緩存中,則拋出一個(gè)錯(cuò)誤。如果它不在高速緩存中,您知道這是一個(gè)有效的請(qǐng)求,并將這個(gè)項(xiàng)處理并存儲(chǔ)在高速緩存中。當(dāng)包已經(jīng)超時(shí)并從高速緩存中被清除時(shí),將錯(cuò)誤消息從先前已被處理更改為令牌失效。使用這個(gè)示例中的高速緩存能夠加速性能,因?yàn)槟梢栽谔峤磺皼Q定是否處理這個(gè)請(qǐng)求。
![]() |
|
使您的 Web 服務(wù)在高度緊張的環(huán)境中順利執(zhí)行對(duì)于技術(shù)的存活非常重要。從短期來看,您將看到許多 Web 高速緩存專家都重新設(shè)計(jì)他們的工具和解決方案以變得更加通曉 Web 服務(wù)。即使在他們?cè)O(shè)計(jì)的進(jìn)候,有時(shí)也會(huì)在服務(wù)級(jí)別智能使用高速緩存中獲益。隨著底層 SOAP 實(shí)現(xiàn)的成熟,您將開始看到設(shè)計(jì)模式參考。這些參考將會(huì)講述如何構(gòu)建快速的和可伸縮的 Web 服務(wù)解決方案。到那個(gè)時(shí)候,運(yùn)行您自己的解決方案吧。即使在聯(lián)網(wǎng)世界到來的時(shí)候,有時(shí)也有使用定制的高速緩存更好執(zhí)行的情況。隨著 Web 服務(wù)越來越受到歡迎,人們對(duì)它的要求也會(huì)增加。當(dāng)您構(gòu)建這個(gè)分布式基礎(chǔ)結(jié)構(gòu)時(shí),請(qǐng)思考一下速度。當(dāng)您通過重復(fù)使用先前的計(jì)算而不是重復(fù)底層的進(jìn)程來提取代碼時(shí),您便贏得了時(shí)間。
聯(lián)系客服