国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

使用BMT消息驅動BEAN和SPRING進行高性能的消息處理

2019-11-18 12:41:00
字體:
來源:轉載
供稿:網友

  簡介

  自從被引入EJB 2.0規范后,消息驅動bean (MDB)已經成為幾乎所有企業java項目的基礎。MDB擁有一個簡單而整潔的API,用戶不需要創建或生成home和local/remote接口,所有這些使得Java開發社區迅速且廣泛地接受了MDB。如您所知,幾乎任何大型J2EE項目都有一個重要部分是與其它系統的集成有關的。一種集成不同系統的可取方法是使用面向消息中間件(MOM)提供的企業隊列(queue)和主題(topic)基礎架構,這要求所有的J2EE服務器都擁有自己的兼容JMS的MOM實現。

  看起來大部分企業J2EE項目取決于JMS消息的接收和/或發送。因此,J2EE架構設計者和開發者就一定要熟悉不同的消息消費和生產方法,因為這可能最終決定項目的成功或失敗。最近,開始出現一些MDB模型的替代方案,例如SPRing和ActiveMQ的消息驅動POJO。當前的MDB模型除了本身是一項有趣有用的技術外,其地位也得以確定,它足夠簡單,并且在J2EE社區中得到了廣泛的采用。

  本文主要關注基于MDB的傳統消費模型。本文將展示如何利用一種更高效的非事務型消息檢索來重構這一場景,而同時仍然保持業務用例的once-and-only-once服務質量(QoS);換句話說,業務代碼應該只處理消息一次,并且不應該丟失任何消息。這是最嚴格的服務質量,也是實現中最有趣的部分。

  傳統的消息消費模型

  可以說,在大多數的J2EE項目中,只要出現消費JMS消息的用例,都會使用MDB。除了最普通的情況外,假如從業務角度來看丟失傳入的消息和/或處理消息副本可以接受,這些MDB都使用容器治理事務(CMT)劃分模型和事務型屬性RequiresNew來部署。為了使這些設置可以生效,應當用事務型的QueueConnectionFactory(或TopicConnectionFactory)來配置MDB。在這樣的設置中,消息消費過程可以用下面的步驟來描述:

  • J2EE容器啟動一個JTA事務。
  • MDB所監聽的隊列/主題的XAResource被添加到事務中。
  • 從隊列/主題消費一條消息,并傳遞給MDB的onMessage()方法。
  • MDB處理消息。任何在MDB處理消息時會使用的事務型資源(比如:數據庫、其它隊列或主題以及JCA適配器)會被添加到步驟1中啟動的同一個JTA事務中(當然,只有在資源支持XA時才可以)。
  • 假如處理成功(onMessage()調用無異常地返回),則J2EE容器會對JTA事務中的所有資源執行一次兩階段提交。因為JTA事務所擁有的資源之一是消費JMS消息的目的地,一旦JTA事務提交成功,消息就會從隊列/主題中移除。
  • 假如處理失敗(onMessage()調用拋出RuntimeException 異常),則J2EE容器會對表示步驟3中消費JMS消息的目的地的XAResource執行回滾,因此消息會停留在隊列/主題中,稍后可能被重新發送。此外,在這種情況下,MDB實例會被銷毀并從處理池中移除。

  如您所見,事務型消息消費的處理非常健壯。這樣的處理模型保證了once-and-only-once的服務質量;換句話說,消息要么被成功地處理一次,要么根本不被處理(可能在超出預定義的重試次數或生存時間或者轉移到停用(dead)消息隊列之后,被從隊列中移除)。

  傳統模型的缺點

  事務型消息消費模型盡管健壯且成功,但是它還是有一些嚴重的缺點。首先,分布式事務嚴重地影響了處理性能(當從本地事務切換到XA時,性能降低50%是不足為奇的)。

  第二個缺點是由CMT造成的,實際的事務提交發生在應用程序代碼之外,在onMessage()調用返回之后。這也許沒什么大不了的(究竟CMT的整體思想是要將應用程序從事務處理中解脫出來),但是存在一些令人不愉快的問題——一些錯誤情況直到事務提交后才進行偵測。例如,在BEA WebLogic Server中,默認情況下,所有由處理CMP bean(創建,更新等等)引起的DML操作都被延遲到事務提交階段。這意味著應用程序可以認為它成功地更新了CMP bean的一個實例,而實際上實際的SQL更新可能會因為違反數據庫的某種約束而失敗。最糟糕的是應用程序代碼不能夠對此做出反應或者只是恰當地進行記錄,因為它看不到異常。

  優化提議

  盡管對延遲的DML操作有一個應急方案(例如,在BEA WebLogic Server中,可以在部署描述符中禁用它),但是這伴隨著性能損失。J2EE服務器將不能再聚集和/或批處理SQL更新(以便執行更高效),或者將它們全部忽略(假如事務稍后被標記為回滾的話)。

  本文認為,采用一種bean治理事務(bean-managed transaction,BMT)方法可以提供同樣的服務質量,并對事務生命周期有更多的控制。應用程序代碼將有機會恢復和/或更清楚地報告錯誤,同時避免上述的CMT模型的所有缺點。此外,我們預料從事務作用域中移除消息檢索能帶來重大的性能提升。

  在討論BMT方法之前,我們需要分析在這種情況下從隊列中消費消息會發生什么。假如我們使用BMT 劃分部署MDB,J2EE服務器不會再把MDB監聽的JSM目的地(隊列或者主題)添加到事務中(事務將會在從隊列中取走消息之后開始)。在這種情況下,BMT MDB應當用部署描述符中的非XA連接工廠配置;否則J2EE服務器會部署失敗。

  根據JMS規范(JMS1.1第一節4.5.2),假如使用AUTO_ACKNOWLEDGE 或者 DUPS_OK_ACKNOWLEDGE模式非事務型地部署消息監聽器,并且onMessage()方法拋出RuntimeException或它的任何子類,則消息會被重新發送。換句話說,重新設計用例來使用BMT是有可能的,假如在處理消息時出錯的話,應用程序代碼可以拋出RuntimeException,消息就會被重新發送(重試)。這種方法很有效,因為使用RuntimeException來表示不可恢復的錯誤是很自然的(例如Spring Framework的異常層次結構基本上全是基于RuntimeException的子類)。消息會重新發送,直到達到一定的次數(可在MOM軟件層配置),之后它通常被丟棄或轉移到停用消息隊列,或者應用程序代碼會計算消息被重新發送的次數,并決定什么時候應當停止嘗試處理以及不處理就消費(假如適當的話,會產生錯誤消息)還是轉移到另外的隊列。



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 余江县| 惠安县| 南召县| 赣州市| 吐鲁番市| 万年县| 英吉沙县| 分宜县| 远安县| 闵行区| 乐陵市| 昭平县| 罗江县| 辽宁省| 闸北区| 巴彦县| 彰化市| 延安市| 兴国县| 梓潼县| 福海县| 武定县| 常山县| 新郑市| 鄄城县| 青田县| 吴江市| 大连市| 马鞍山市| 阳信县| 外汇| 方山县| 定兴县| 黑水县| 宜州市| 洪洞县| 梁河县| 攀枝花市| 革吉县| 武邑县| 土默特右旗|