4. 如果在同步點控制之下使用MQGET,在所有MQGET調用之后,必須檢查消息的回滾次數(Backout Count)。
如果某個消息是在同步點控制之下讀取的,并且由于某種原因消息被回滾,消息描述符中(Message Descriptor)的BackoutCount字段的值將被加1,你需要判斷該數值,如果它大于某個閾值,你需要使用其它手段來處理該消息。否則,在某些情況下會導致讀取消息-消息被回滾-再讀取消息-消息再被回滾的死循環。
例如:你使用了觸發機制設定當隊列中消息到達時,觸發某個應用程序,該應用程序在MQ XA Resource Manager的控制之下,讀取消息,并且利用其數據對數據庫進行更新,假設數據庫出現問題,無法成功進行數據庫操作,消息將被回滾;這時,又滿足了觸發條件,又會觸發起該應用程序,周而復始,陷入死循環。在這種情況下,你必須在程序中加入對BackoutCount的判斷。
5. 當處理backout消息時,可以使用隊列的BOTHRESH 和 BOQNAME屬性。
如4 中所言,如果某個消息是在同步點控制之下讀取的,并且由于某種原因消息被回滾,消息描述符中的BackoutCount字段的值將被加1,你需要判斷該數值,如果它大于某個閾值,你需要使用其它手段來處理該消息。在處理該消息的應用中,你可以將其與設定的閾值做比較,這時,閾值會被寫死在程序中,為了提高其靈活性,你可以使用隊列的BOTHRESH 和 BOQNAME屬性。這樣,你可以在例外處理中,利用MQINQ查詢得到閾值的大小,如果超出,可以將消息轉發到BOQNAME指定的隊列中,繼而對該隊列進行相應的處理。這種方法大大增強了應用程序的靈活性。
6. 在使用MQOPEN, MQPUT 和 MQGET調用時,要使用FAIL_IF_ QUIESCING的選項。
MQ 系統本身和使用它提供的服務的用戶應用程序之間是互相獨立的,必要時,我們可能要停止MQ系統,這時,我們不但希望新的應用不能連接,并且希望所有已連接的應用能夠立即停止。為了使所有的應用程序能夠快速得知MQ系統正在停止的信號,在上述MQ API中,必須設置FAIL_IF_ QUIESCING的選項。
如果不設置FAIL_IF_ QUIESCING的選項,當MQ系統停止時,所有應用將繼續運行,這樣會影響MQ系統的停止,從而導致MQ停止需要很長時間,同時可能導致我們必須手工殺掉那些沒有設置該選項的應用程序。
7. 消息描述符的不同字段的使用方法
在MQ 的消息描述符MQMD中包含了很多字段,這些字段大部分是一些保留字段,例如:MsgID表示消息的唯一標識,如果你不指定,MQ系統會為你自動產生一個,并保證其唯一性;PutAppType, PutAppName, PutDate, PutTime是系統自動產生的,表示哪個應用何時將消息發送到隊列中;再如:GroupId, MsgSeqNumber, Offset, MsgFlags是與消息分段和消息分組相關的控制信息;除了這些系統自動產生無法更改的字段和有特殊用途的字段之外,如果您想選擇某些字段為己所用,將其設定為自己應用程序中某個有意義的標識,你可以使用CorrelId和Feedback字段,但是,按照慣例,CorrelId常常被用于在請求/應答通訊模式中來表示請求消息和應答消息之間的關聯;因此,我們可以靈活使用Feedback字段,利用該字段來進行一些應用程序控制。當我們接收到某個消息之后,我們可以檢查Feedback字段,根據Feedback字段值進行相應的處理。
8. 消息永久性屬性的確定
永久性消息保證了消息在系統和網絡等故障下的安全可靠,但是同時從性能角度來講會比非永久性消息要差,因此,要從不同的角度進行權衡和分析,然后決定消息的永久性屬性。當對性能要求非常高,可靠性要求相對不高時,可以首先考慮采用非永久性消息,在消息決不允許有任何丟失,并且在丟失之后又無法重新發送時,要使用永久性消息。
9. 當指定消息的永久性和非永久性屬性時,最好利用應用程序顯式地指定,不要使用"defined as queue"的方法來指定。
消息的永久性和非永久性是消息本身的屬性,多數情況下,只有消息的原始發出者才了解丟失消息將產生的重大影響,因此,消息的原始發出者應在應用程序中顯式地指定消息的永久性,如果將其定義為依賴于隊列的該屬性,就會比較被動,當隊列的永久性屬性(DEPSIST)被意外地設為NO時,就會有丟失的風險。
10. 應用程序可以將請求消息的永久性屬性為No,即對于請求消息使用非永久性消息。
一般情況下,請求消息丟失對應用系統不會產生嚴重的影響,如果出現請求消息丟失的情況,我們可以重新發送,因此,不必將請求消息設置為永久性消息。把請求消息設置為非永久性消息的另外一個好處是,系統不需要對非永久性消息記錄日志,從而減少I/O操作,提高系統的性能。
11. 在異種操作系統平臺上使用MQ傳輸消息時,將消息格式設置為MQFMT_STRING。
MQ 的一大優勢之一,是對built-in(內置的)消息格式,可以實現不同操作系統平臺間、不同系統字符集之間的數據轉換,如開發平臺ASCII碼和主機 EBCDIC碼之間的轉換。為了實現該數據轉換,MQ必須獲知本身和對方MQ系統的隊列管理器的CCSID和Encoding以及消息的格式。一般而言, CCSID和Encoding會被自動設置和處理,不需要應用程序關心,但是,消息的格式必須由應用程序指定,對于MQ內置支持的消息格式,MQ可以自動轉換,這些消息格式由MQFMT_*來指定。鑒于應用程序數據都可以用MQFMT_STRING來表示,并且MQFMT_STRING是MQ內置支持可以轉換的格式之一,你可以使用它來表示你的消息格式,同時,對于數字型消息,你需要使用atoi, itoa等函數實現數字型和字符型之間的轉換。
12. 對大消息的處理
MQ 支持單條消息的最大長度為100M,隊列管理器、隊列、通道支持的最大消息的缺省值為4M,即使如此,我們卻應該根據不同的網絡類型和帶寬,具體地確定不同情況下單條消息的合適大小。例如:如果在撥號網絡或網絡帶寬較窄的情況下,我們將單條消息的大小設置得太大,就會影響傳輸效率,在這種情況下,一定要使用MQ的分段功能將消息進行分段處理,確保每一個物理消息的大小適當,MQ會自動維護整個邏輯消息的完整性,并且可以在接收端一次性將其取出。
13. 如何使用MQ的請求/應答通訊模式來處理同步的消息處理模式。
大家知道,MQ的異步處理模式是非常強健的,同時它也支持同步的消息處理,例如MQ的client-server通訊就是一種典型的同步工作模式,對于 server-server通訊,我們也可以實現同步工作模式,這里就涉及到如何巧妙地使用MQ提供的消息生命周期的功能。這時,對于請求消息和應答消息我們最好為其設置生命周期。
典型的應用案例如下:假設系統A向系統B發出請求,調用B上的某個交易,這里,我們首先要設置請求消息的生命周期,并且在消息到期時將消息丟棄,如果在消息發出之前消息過期,它就會在進入通道之前,被MQ系統丟棄;如果當消息到達目的地之后,在被對方應用程序取走之前消息過期,它也將被MQ系統丟棄。系統B上的交易便不會被調起執行。對于應答消息,我們也設置它的生命周期,與請求消息不同的是,我們設置在消息到期時將其轉發到另外一個特定的隊列中,這時,如果系統B上的交易執行完之后,會產生應答消息,如果由于通訊等原因,該應答消息在到達系統A時應用程序設置的Timeout時間已經超出,應用程序必然認為系統B上的交易沒有被執行,也不會處理該應答消息,這樣,應答消息便會過期,當它過期時,根據我們的設置,它會自動被MQ系統轉發到特定隊列中,我們另設專門的應用程序對此進行沖正處理。
文章來源于領測軟件測試網 http://www.kjueaiud.com/