隨著Web服務的應用不斷增多,對很多項目來說,只解決異構平臺的分布式通信問題已經不夠了。盡管互操作性是很多人考慮Web服務時的首要選擇,但分布式系統還帶來了很多難題使得互操作性不那么容易實現。在下面的文章中,我們將看看如何解決Web服務中的另一個分布式技術問題:可靠性。
可靠性一個關鍵概念,在涉及到金融相關數據時尤其如此。天氣預報的Web服務代理信息與提供股票市場定單的Web服務是不能相提并論的。前者可以忍受網絡失敗并且接受新的請求而不產生大的影響,而如果后者沒有必要的手段來處理這些問題就會產生嚴重的后果。基于此,在OASIS的贊助下出現了一個專門處理可靠性問題的Web服務說明書:WS-Reliability .
與其它Web服務說明書一樣,WS-Reliability體現出可組合性的特點,它允許你按照需求混合匹配各種SOAP行為。通過這種方式,任何基于SOAP的應用都可以獲得該可靠性層的好處,只需簡單地添加SOAP頭信息就能使用WS-Reliability中的任何規則。例如:
- 保證傳送至少一次——發送的消息必須傳送到接受端,要么給發送端一個發送失敗的說明。
- 刪除重復信息——最多發送一次,檢測重復信息并在接受端刪除。
- 保證消息順序——消息按照順序被發送
盡管WS-Reliability基于SOAP提供協議以某種方式傳送有效負載等可靠數據,但還是要通過一個高層棧的翻譯或處理來決定是否執行一個可靠通信。在WS-Reliability's中,高層棧是指能夠進行轉化的一種特殊環境,它可以是ESB或折like PHP/PEAR、 Java/Axis等Web服務框架。
這說明,就算用WS-Reliability實現的服務能夠無縫地與其它服務交互,但唯一使用這些信息,還必須學習一個特殊的Web服務棧。有個例子,Apache Software Foundation創建的名為Sandesha 的WS-Reliability實現被加入了Axis框架中。而Axis框架是該基金會創建的一個Java Web服務棧。
現在,我們來看看Sandesha如何利用Axis框架創建可靠的Web服務。我們并不深入到細節,你可以查閱Sandesha的文檔來看看它是如何加入到Axis架構中的。或者好好閱讀Axis文檔,如何你對它不熟悉的話。
我們的情景是一個Web服務客戶端向一個股票報價系統發出一個可靠請求。表單1.1顯示了我們的客戶端如何使用Sandesha/Axis。
Listing 1.1
import org.apache.axis.client.Service; import org.apache.axis.client.Call; import org.apache.axis.encoding.XMLType; import org.apache.sandesha.Constants; import org.apache.sandesha.SandeshaContext; import javax.xml.namespace.QName; import javax.xml.rpc.ParameterMode; public class StockQuoteClient { ?? private static String targetURL = "http://acmestockquote.com/axis/services/StockQuote"; ?? public static Double stockQuote(String symbol) { ??????? Double priceObject = new Double(0.0); ?try { ???????? Service service = new Service(); ? Call call = (Call) service.createCall(); ? SandeshaContext ctx = new SandeshaContext(); ???? ctx.initCall(call, targetURL,"urn:wsrm:stockQuotePrice",Constants.ClientProperties.IN_OUT); ?????????????? call.setOperationName(new QName("acmestockquote.com", "stockQuotePrice")); ???????? call.addParameter("Text", XMLType.XSD_STRING, ParameterMode.IN); ???????? call.addParameter("Seq", XMLType.XSD_STRING, ParameterMode.IN); ???????? call.setReturnType(org.apache.axis.encoding.XMLType.XSD_DOUBLE); ????? ctx.setLastMessage(call); ?priceObject = (Double) call.invoke(new Object[]{"StockQuote", symbol}); ??????? ctx.endSequence(); ?} catch (Exception e) { ??????????? e.printStackTrace(); ?} ??????? return priceObject; ?? } ?? ??? public static void main(String[] args) { ??????? StockQuoteClient.stockQuote("SLB"); ?StockQuoteClient.stockQuote("BCA"); ?StockQuoteClient.stockQuote("SNY"); ??? } } |
??????StockQuote方法包括我們的業務邏輯。首先,使用了Service和Call類,每個對象實例可以被基于Java Axis的Web服務客戶端正常使用。在上面的例子中,它們都被保證可靠性的層SandeshaContext使用。
SandeshaContext用來維護在客戶端和服務器端之間交互的狀態。這就是為什么Call方法在ctx.initCall和ctx.endSequence之間被嵌套的原因。而它們正代表了Sandesha啟動和結束一個可靠的過程。實際上,Call方法產生了一個不能被標準Web服務操作探測到的錯誤,例如被確保的傳送或者重復的請求。Sandesha能夠通過它的上下文來決定如何輸出。
在表單中,你還能看到在ctx.initCall方法中有urn:wsrm:stockQuotePrice的命名空間。它代表了被加入到客戶端請求中的額外SOAP頭信息,它能被Web服務提供者識別用來完成可靠性過程。在Axis/Sandesha的例子中,盡管二者的結合提供了對構建具有翻譯WS-Reliability客戶端能力的服務提供者的支持,但它還具有本文沒有提到的其它功能。不過,你應該注意到Axis/Sandesha框架已經與WS-Reliability進行了成功的測試,包括不同的Web服務棧上的客戶端與服務器端,包括IBM、Microsoft 和Systinet。
至此,我們對Sandesha和WS-Reliability下一個結論。在解釋了如何利用Web服務的可靠性特征后,你現在可以考慮實現其它的企業消息技術,例如至今可靠的分布式通信產品JMS (Java Messaging Service),并且用WS-Reliability提供同樣的可靠性,但要繼承平臺無關的Web服務的所有優點。