本系列文章的第 1 部介紹了 WSN (WebService Notification) 和 WSRF (WebService Resource Properties Framework) 兩個規范,第 2 部分將為大家展示一個基于 WSN 和 WSRF 的具體應用。在第 3 部分中,我們將對程序架構進行調整,在Notification Producer和Notification Consumer之間增加一個間接層:ESB,然后將我們之前實現的WSN應用遷移到ESB上,最后進行測試。
本系列文章的第 1 部分中介紹了WSN(WebService Notification) 和WSRF(WebService Resource Properties Framework) 兩個規范;第 2 部分中為大家展示一個基于WSN和WSRF的具體應用。在這個WSN應用中,Notification Producer和Notification Consumer之間是一種端到端的直接交互。在第 3 部分中,我們將對程序架構進行調整,在Notification Producer和Notification Consumer之間增加一個間接層:ESB,然后將我們之前實現的WSN應用遷移到ESB上,最后進行測試。
![]() ![]() |
![]()
|
2. 在SOA中構建WSN應用
在第 2 部分我們實現的WSN應用中,Notification Producer和Notification Consumer之間是一種端到端的直接交互。在一個復雜的企業計算環境中,如果廣泛采用這種直接的端到端的交互,那么隨著企業內應用程序的增加和復雜度的提高,最終應用程序之間的關聯會逐漸變的非常復雜,形成一個網狀結構,這將帶來非常昂貴的系統維護費用,同時也使得IT基礎設施的重用變的困難重重。正如計算機領域的那句名言:"有難以解決的問題,那么就增加一層",要解決上面描述問題,我們需要對我們的程序架構進行調整,在Notification Producer和Notification Consumer 之間增加一個間接層:ESB。在這一部分,我們將首先在WebSphere Application Server V6上利用SiBus建立一個ESB,然后將我們之前實現的WSN應用遷移到ESB上,最后進行測試。目前已經有大量的文章和書籍介紹SOA,所以這里我們不再對SOA的基本概念進行詳細介紹,如果您需要這方面的參考,請查閱本文最后所附的參考資料。
2.1 SOA中的WSN應用實例架構
圖 1 是之前的WSN應用遷移到ESB上后的系統架構圖:
這里大家可以看到Notification Producer和Notification Consumer之間的調用已不再直接把消息發給對方,而是將消息發送給ESB,然后通過ESB中的路由機制路由到目標服務,這樣做的好處是:首先這樣的結構將之前描述的復雜的網狀結構的復雜性歸納到了ESB的服務選擇和消息路由之上,大大降低了系統架構上的整體復雜性,這一點在有多個應用程序之間需要發布,訂閱事件時體現的更為明顯,其次,在這樣的架構下,我們可以享受到服務替換,中介,監控等等ESB的基本特性,而且隨著我們提升ESB的能力模型,我們還可以享受到ESB的一些如QoS這樣的高級特性。
2.2 在WebSphere Application Server V6中構建ESB
要將我們的WSN應用遷移到ESB上,我們首先需要創建一個ESB,這里我們使用的應用服務器是WebSphere Application Server V6中,我們將使用該應用服務器的SiBus來創建我們的ESB,具體步驟如下:
登陸WebSphere Application Server的管理控制臺,選擇Service Integration'Buses,然后在右邊的窗口中選擇New,然后在General Properties下的Name屬性處輸入Demo作為我們的Bus(總線)的名字,最后直接點OK創建我們的總線,如圖 2 所示:
在一個總線創建成功后,我們需要至少為它添加一個成員,對于每個添加到總線中的成員,該WebSphere實例上都會創建一個消息引擎。這里我們需要在總線列表中點擊我們剛剛創建的總線Demo,然后選擇Bus Members,接著選擇ziqiangNode01:server1作為總線的成員(這里ziqiangNode01是本文試驗環境的NodeName),其他都接受默認值,完成總線成員的添加,最后我們會看到總線成員列表中會列出我們新添加的成員:
在WebSphere Application Server V6的SiBus上,所有的消息都會被轉換為SDO(Service Data Object)對象,因此我們需要一個用來存儲SDO對象的子系統,另外SiBus還將把各種WSDL的定義存放在這個SDO存儲子系統中,因此這里我們需要首先定義這個SDO存儲子系統,在WebSphere Application Server安裝的時候,會缺省安裝CloudScape數據庫,這里我們就將SDO存儲子系統建立在CloudScape上,當然您也可以選擇其他的數據庫。創建SDO存儲子系統的步驟非常簡單,假定您將WebSphere安裝到了<WAS_HOME>下,那么首先進入目錄<WAS_HOME>/bin,然后執行下列命令:
|
如果命令執行成功,您最終會看到如下返回信息:
|
同時在WebSphere的管理控制臺,選擇Applications'Enterprise Applications,您會看到有一個應用程序SDO_Repository被列出來。如圖 5 所示:
為了使我們的總線能接收到客戶端對WebService的調用請求,我們還需要配置endpoint listener。而為了使得我們的總線能調用其他的WebService,我們還需要配置一個Resource Adapter。首先我們先來配置Resource Adapter,在<WAS_HOME>/bin目錄下,執行下面的命令:
|
如果命令執行成功,您最終會看到下面的信息:
|
同時,登錄WebSphere的管理控制臺,選擇Resources'Resource Adapters,您會看到列表中有一個名為SIB_RA的Adapter:
接下來我們配置endpoint listener。我們知道具體傳送SOAP消息的協議可能有多種(如HTTP,JMS),對于每一種具體的協議都有配置專門的endpoint listener,在本文中我們使用HTTP協議。對每一種具體的協議,兩個endpoint listener會被創建,一個可以用來處理來自企業外部的請求,另一個可以用來處理來自企業內部的請求。首先執行下面的命令:
|
如果該命令執行成功,您會看到下面的信息:
|
接著執行下面的命令:
|
如果該命令執行成功,您會看到下面的信息:
|
同時在WebSphere的管理控制臺,應用程序列表中,您會看到新安裝了3個應用程序,它們是:sibws.ziqiangNode01.server1,sibwshttp1.ziqiangNode01.server1,sibwshttp2.ziqiangNode01.server1。 如圖 7 所示:
在上述命令執行成功后,我們還需要登錄WebSphere的管理控制臺,選擇Application Servers,然后在右邊的窗口中點擊server1,然后選擇Endpoint Listeners,如圖 14 所示:
選擇New,在General Properties 下,輸入SOAPHTTPChannel1作為名字,輸入http://localhost:9080/wsgwsoaphttp1/作為URLRoot和WSDL Serving HTTP URL root的值,這里9082是本文試驗環境所使用的端口,缺省情況下是9080。其他參數接受默認值
點擊OK,我們會在endpoint listener列表中看到SOAPHTTPChannel1:
最后為了讓剛剛配置的endpoint listener關聯到我們的總線 Demo,在endpoint listener列表中點擊SOAPHTTPChannel1,然后點擊Connection Properties,然后點擊New,并選擇我們的總線 Demo,最后點擊OK完成配置:
同時選擇Service Integration'Buses,然后在總線列表中點擊Demo,然后選擇Destinations,您會在列表中看到一個名為ziqiangNode01.server1.SOAPHTTPChannel1Reply的Destination。
好了,到現在為止,我們已經成功地安裝了SDO存儲子系統,為SiBus配置了Resource Adapter和Endpoint Listener,下面我們將把我們前面實現的WSN應用我們剛剛創建的總線上來。
2.3 將HRService和Directory Service遷移到ESB上來
在本文上一節所創建的總線在整個系統中所處的是一個中介的地位,它本身并不能提供我們需要的HRService和Directory Service,因此我們首先需要安裝這兩個服務,安裝的方法非常簡單:在WebSphere的管理控制臺,選擇Applications'Install New Application,選擇本文所附的pubscribe_all_in_one.war,并使用pubscribe_all_in_one作為context root,點擊Next,在后繼的步驟中分別選擇Generate Default Bindings以及Deploy Enterprise beans,其他的參數都接受缺省值,完成安裝。
最后在application列表中我們會看到一個名為pubscribe_all_in_one_war的應用程序,剛剛安裝完成,它的狀態是停止的,我們需要將它啟動。
由于pubscribe_all_in_one_war中有些類和WebSphere自帶的類沖突,我們需要讓WebSphere優先加載定義在pubscribe_all_in_one中的類,所以在應用程序列表中點擊pubscribe_all_in_one_war,然后選擇Web Modules,您會看到一個名為pubscribe_all_in_one.war的module,點擊它,然后將class loader mode該為Parent Last,這一點非常重要,否則pubscribe_all_in_one在運行時刻會出現錯誤。
注意,由于我們的程序現在遷移到了WebSphere上,因此我們需要修改一下WEB-INF/classes/wsrf-config.xml中baseWebappUrl,請將字符串"http://$HOST_NAME$:8080/pubscribe_all_in_one" 中的8080替換為您的應用服務器所使用的端口,在本文的試驗環境中使用的端口是9082,將"pubscribe_all_in_one"替換您所設置的Context Root.
在我們安裝了HRService和Directory Service后,我們需要配置我們創建的總線使它承擔起中介的角色。在WebSphere Application Server V6中,如果總線需要調用一個外部的Service,我們需要在總線上來創建一個Outbound Service,通過這個Outbound Service,總線內部的SOAP消息可以被發送到其他的WebService。簡單來說,我們可以把Outbound Service看作是外部Service的映像。我們可以通過WebSphere的管理控制臺完成Outbound Service的創建,對于每個外部Service WSDL文件中的Service元素,我們的總線上都會生成一個Service Destination,而對應WSDL文件中的每個Port,在總線上都會生成一個Port Destination,從總線發往外部Service的SOAP消息,從總線內的其他Destination路由到Service Destination,然后再通過Port Destination發送到外部的服務提供者。
在我們的例子中,我們需要通過總線把發送給HRService和Directory Service的SOPA消息通過總線路由到真正的服務提供者,也就是我們的pubscribe_all_in_one這個應用程序。我們首先來為HRService創建Outbound Service,在WebSphere的管理控制臺中創建一個Outbound Service是一個簡單的配置步驟:
點擊Next,在向導的第二步,選擇服務{http://ibm.com/wsn/hr}HRService
點擊Next,在向導的第三步,選擇Port hr
點擊Next,在向導的第四步,輸入HRService作為Outbound Service的名字
點擊Next,在向導的第五步,選擇ziqiangNode01:server1作為總線的成員,最后點擊Finish完成Outbound Service的創建。
對于Directory Service也可以類似地創建,這里不再贅述。最后我們在Outbound Service的列表中可以看到我們所創建的服務。
同時我們可以在總線的Destination列表中看到新創建了一個Service Destination和一個Port Destination
由于總線現在充當了一個中間人的角色,因此對HRService和Directory Service的調用,SOAP消息都不是直接發送給這兩個服務的,而是發送給我們的總線,然后再由總線轉發出去。為了使得總線能接收SOAP消息,我們需要在總線上創建一個Queue Destination以及一個Inbound Service代表要調用的服務。在Inbound Service創建完成后,我們可以將其發布,將portType,bindings以及endpoint 地址等信息提供給服務調用者。我們首先為HRService創建一個Queue Destination:
首先在WebSphere的管理控制臺,選擇Service Integration'Bus,選擇我們的總線Demo,然后選擇Destinations,點擊New,選擇Queue作為Destination的類型:
點擊Next,在向導的第一步,輸入HRInboundDest作為標識符:
點擊Next,在向導的第二步,選擇總線成員ziqiangNode01:server1
接下來我們需要為HRService創建Inbound Service:
首先選擇Service Integration'Bus,選擇我們的總線Demo,然后選擇Inbound Service,點擊New,在向導的第一步選擇URL作為WSDL Location Type,輸入http://localhost:9082/pubscribe_all_in_one/wsdl/hr.wsdl作為WSDL Location的值:
點擊Next,選擇{http://ibm.com/wsn/hr}HRService
點擊Next,輸入HRInboundDestInboundService作為Inbound Service的名字,選擇ziqiangNode01:server1:SOAPHTTPChannel1作為Endpoint Listener。這里我們選擇的listener,如果您還記得的話是在介紹創建ESB時在WebSphere的管理控制臺中創建的。
點擊Next,由于這里我們不使用UDDI,所以直接點擊Finish完成創建對于Directory Service,我們可以用同樣的方法為其創建Inbound Service,這里不再贅述,最后我們可以在Inbound Service的列表中看到我們創建的服務:
現在,為了讓我們的總線充當中介的角色,并讓它能正確的路由SOAP消息,我們還需要最后為我們的總線配置消息路由,對于HRService,我們需要把HRService的Inbound Service對應的Queue Destination上接收的SOAP消息路由到HRService對應的Outbound Service的Service Destination上,而這個Service Destination則會將SOAP消息自動路由到相應的Port Destination上,最后消息被轉發到HRService。具體的配置步驟如下:
選擇Service Integration'Buses,點擊我們的總線Demo,選擇Destinations,選擇HRService的Inbound Service對應的Queue Destination "HRInboundDest",在Default forward routing path下輸入:Demo:http://ibm.com/wsn/hr:HRService,這里的格式是<Bus Name>:Destination Name.
對于Directory Service的路由配置,請讀者作為練習配置。
2.4 在SOA的環境中測試我們的WSN應用
現在我們的WSN應用已經完全遷移到SOA的環境來了。在介紹如何使用Apache的Pubscribe創建WSN應用時我們講到,為了避免硬編碼,我們把Notification Producer和Notification Consumer的Endpoint Reference分別寫在了<app_name>/epr/directory.txt和<app_name/epr/hr.txt中,現在,由于我們的總線充當了中介的角色,SOAP消息都是發送給總線,然后再由總線轉發的,因此這兩個文件也需要做相應的修改,具體的修改值,我們可以通過發布Inbound Service,然后從獲取的WSDL文件中得到:
在WebSphere的管理控制臺,點擊Service Integration'Buses,選擇Demo,選擇Inbound Services,選擇HRInboundDestInboundService,選擇Publish WSDL files to zip file:
將HRInboundDestInboundService.zip保存在本地
對于Directory Service,我們可以類似地修改directory.txt。
下面我們開始正式的測試:
通過瀏覽器訪問http://localhost:9082/pubscribe_all_in_one/hr.jsp,您可以看到如下界面:
訪問http://localhost:9082/pubscribe_all_in_one/directory.jsp,您可以看到如下界面:
在Directory Service的界面中,點擊SUBSCRIBE,您會看到一條消息說訂閱成功,點擊return按鈕,然后您將在如下界面中接收消息:
在HR Service的界面中,點擊Trigger Notification,您將看到:
回到Directory Service的界面,點擊Get Last Notification,你將看到:
這里我們看到,將我們的WSN應用遷移到SOA的環境中之前和之后,對于用戶來說是感覺不到變化的;通過之前我們的配置步驟我們也可以看到,對于Service的客戶端或者說是調用者,依然不需要修改代碼,重新部署;而對于服務的提供者來說,也一樣不需要修改代碼。通過簡單的配置我們就可以享受到ESB的服務選擇,消息路由,中介服務等基本特性,而且隨著ESB能力的提升,我們還可以進一步享受QoS等高級特性,同時卻基本不必對原有系統進行改動,這也就是我們要將WSN應用遷移到SOA環境中來的重要原因。
在遷移WSN應用到SOA環境之前,我們為讀者詳細解釋了在整個應用的運行過程中所發送和接受的消息,現在您依然可以觀察這些SOAP消息。同時您還可以利用總線的Mediation特性編寫一個簡單的Mediator來記錄流經每個Destination的SOAP消息,進而觀察SOAP消息是如何路由的。由于本文的主要目的是介紹在SOA環境中構建WSN應用程序,因此如何編寫Mediator就不再這里講述了。如果您感興趣,可以參考本文后面的參考資料。
![]() ![]() |
![]()
|
3.總結
在本系列文章(三部分)中,我們首先為大家簡單的介紹了WSN規范,在WSN應用中的關鍵角色Notification Producer,Notification Consumer。 接著介紹了WS-Resource的基本特性并結合實例介紹了訪問模式。在有了WSN和WSRF的基礎后,我們為大家介紹了一個WSN應用的具體例子,接著我們采用Apache對于WSN和WSRF的實現Pubscribe,遵循其開發步驟實現了這個WSN應用,并對應用中的消息進行了詳細解釋以幫助大家進一步理解WSN和WSRF,最后我們將這個WSN應用遷移到了SOA環境中,詳細描述了具體的遷移方法以及將其遷移到SOA環境的好處。在文章中我們涉及了較多的配置步驟,但是熟能生巧,相信隨著您實踐的增加,您會發現這些配置其實并不復雜,而它卻能使您的系統架構更加靈活、標準和健壯。
![]() ![]() |
![]()
|
下載
名字 | 大小 | 下載方法 |
---|---|---|
ws-wsn.rar | 11.170K | HTTP |