基于消息Bean的EJB異步通信Bromon原創 請尊重版權
異步通信是一個提升程序執行效率的很重要的手段,而性能問題又是EJB誕生以來一直都很受關注的話題。EJB執行效率不高的原因是客戶端需要查詢和調用遠程接口,而本身在處理數據是很快的,畢竟EJB有比較完善的緩沖機制,幾十萬的app server也不是白吃內存的。客戶端程序如果能夠采用異步通信,只負責以消息的形式發送請求和需要處理的數據,不用等待系統查詢、調用遠程接口,可以節省大量時間,這也是EJB 2.0中引入消息驅動Bean的一個重要原因。J2EE的消息機制允許你以消息的形式傳遞對象,我們可以利用它實現很多應用。
在最近正在寫的一個考試系統中,系統把學生對每一個題目的回答都實時記錄到數據庫,這樣做會有比較頻繁的數據庫操作,對性能有比較大的影響,但是可以讓學生的每一次答題都得到永久性保存,避免因為意外死機或異常退出造成學生提交的答案丟失。毫無疑問,數據的安全可靠是第一位的,但是上百個學生并發操作,這個負載也是很巨大的。為了在穩定和性能上謀求平衡,我們考慮這樣一種模型:
◆在服務器端建立一個永久性的隊列,該隊列可以保證數據安全,即使服務器意外重啟,里面的對象也不丟失。并且有一種機制保證隊列中的對象只會被處理一次。
◆客戶端把答案數據封裝成javabean,然后提交到這個隊列中,提交之后不必等待數據處理完成,直接進行以后的操作,產生新的數據后繼續往隊列里存放,不必去關心數據什么時候會被處理。
◆服務器以FIFO的順序處理隊列中的數據包。
結構大致如下圖:
很明顯,這里只提供一種單向通信,但是并非被迫,完全可以在建立另外一個隊列,存放返回的消息,對應的消息通過消息ID進行關聯。以消息bean為核心的java消息服務(JMS)實際上就是這樣一個框架。
首先設計一個操作答案數據表的類:
它包含增加答案的方法和修改已有答案的方法,在實際的項目中,它由一個映射數據表的CMP Entity Bean和一個封裝程序邏輯的SessionBean構成,是一個典型的session facade模式。實際的系統大致是這樣:
在一個系統中同時使用CMP和Hibernate來做映射,是一個非常怪異的設計,這樣做只是為了使系統更有研究和討論的價值,實際應用中恐怕我自己也要仔細考慮是否采用BMP代替Hibernate。
編寫消息bean之前,首先定義消息中要傳遞的是什么對象:
下面是消息Bean的代碼:
消息如何保障安全呢?有兩個手段,一是使用消息驗證,客戶必須提供匹配的帳號密碼才能訪問消息中的數據。二是對消息中的對象加密,客戶必須持有對應的密鑰才能獲得對象。