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系統轉發到特定隊列中,我們另設專門的應用程序對此進行沖正處理。
14. 對消息類型的設置。
通常情況下,我們不要求用戶一定去設置消息的類型,設置消息類型的方法是在消息描述符MQMD的MsgType字段,消息類型有datagram, request, reply, report等若干種。但是為了更好地對消息進行管理,我們必要時要設定消息類型,從而對不同的消息進行處理。例如,當reply消息和report消息都被發送到同一個應答隊列時,我們可以根據消息類型的不同對其進行不同的處理。
15. 對消息轉換的設置。
通常,當需要進行消息轉換時,我們有兩種方法來進行設置:一種方法是在調用MQGET時設置MQGMO_CONVERT的讀取消息選項;第二種方法是將發送端通道的convert屬性設置為yes。對比二者,我們推薦使用第一種方法,它的優勢在於:它避免了消息通道代理程序對消息的轉換,從而提高了通道的性能;其次,當一對多傳輸時,避免了對不同的目標系統使用不同的轉換算法,而統一放在接收端進行。
當我們不需要進行格式轉換時,使用在MQMD中將消息格式Format字段設置為MQFMT_NONE的方法來表示,MQFMT_NONE表示忽視任何格式轉換。
16. 應用程序最好不要在MQGET和MQPUT調用時使用過大的消息緩衝區,從而減少隊列管理器對內存的需求。
當應用程序發出MQGET和MQPUT調用時要設定用於裝載消息的數據緩衝區大小,MQ系統將據此來分配內存,如果使用過大的消息緩衝區,隊列管理器就會分配較大的內存來處理這些調用,從而造成內存浪費,影響性能。如果我們在接收端不知道消息的大小,為了不至於設置一個很大的緩衝區去接收數據,我們可以在真正的MQGET之前先使用Browse方式來瀏覽一下隊列中的消息,根據瀏覽到的消息的MQMD的OriginalLength字段的數值來確定消息緩衝區的大小,然後再使用MQGET真正的將消息讀取出來。
17. 在設定消息的優先級時,不要直接在消息描述符中設置,最好設置隊列的優先級,然後使用”defined as queue”來設置消息的優先級。
優先級是消息的屬性之一,當應用發生變化時,我們可能需要改變消息的優先級,如果我們將其寫死在程序中,就會影響程序的靈活性。如果藉助於隊列的優先級來設置消息的優先級,系統管理員可以根據需要,通過改變隊列的DEFPRTY的屬性來更改其優先級,而無需改變應用程序代碼,這樣可以大大提高系統管理和網絡管理的靈活性。
18. 請求型應用在打開請求隊列時,最好不要使用MQOO_OUTPUT選項。
請求隊列可以是本地隊列,也可能是遠程隊列,本地隊列是既可讀又可寫的,而遠程隊列是只可寫(MQOO_OUTPUT)的。通常,請求型應用一般都是需要將請求發送到請求隊列中,對隊列的操作都是MQPUT,這時,隊列的類型不會有影響,因為本地隊列和遠程隊列都是可寫的。但是,如果某個請求型應用需要讀取請求隊列,則要求請求隊列一定是本地隊列,這時就不能使用MQOO_OUTPUT選項。因此建議在打開請求隊列時,最好不使用MQOO_OUTPUT選項,可以使得不同的應用之間很容易移植,而且當隊列屬性改變時,不會對應用程序造成影響。
19. 與數據庫交互時,MQPUT 和 MQGET必須使用同步點控制,即使用MQ的兩階段提交功能,來保證數據的一致性和完整性。
為了保證數據庫操作和MQ操作同時成功或同時回滾,需要在做MQPUT 和 MQGET調用時,使用MQPMO_SYNCPOINT和MQGMO_SYNCPOINT選項將隊列操作和數據庫操作作為一個事物來完成。這樣,如果數據庫出現問題導致操作失敗時,消息可以被正確回滾;否則,會導致數據不一致的現象。
20. 與數據庫操作相關的隊列消息的屬性最好設為永久性消息,即消息的persistence屬性應設為yes,並且永不過期。
由於與數據庫操作相關的消息的重要性很強,它必須被設置為永久性消息,被MQ系統記錄日誌,從而在隊列管理器重新啟動或機器重啟時不會丟失。另外,在”Send and Forget”通訊模式之下,由於這是典型的異步通訊模式,消息何時被處理是不確定的,為了防止消息超時,我們應將其生命周期設置為永不過期。
21. 對消息做了修改或者轉發的應用,最好傳遞原始消息的identity context(身份鑒別上下文)信息。
每個MQ的消息都有其特定的鑒別上下文,通過消息描述符(MQMD)的相關字段來表示,它代表了消息是由誰產生的,當消息在MQ網絡中傳輸時,該上下文應該必須被保留。當消息被另外的用戶修改或者轉發時,需要修改其上下文,將其原始的上下文重新賦進去。這主要是處於安全的考慮,通過上下文,可以獲得消息產生者的信息。
22. 保持永久性動態隊列名稱的唯一性,確保同一個應用多次調用/運行產生的動態隊列的名字唯一性。
當應用程序需要動態產生應答隊列時,它可以產生臨時性動態隊列和永久性動態隊列,某些情況下,將利用永久性動態隊列保留一些可恢復的消息,這意味着該永久性動態隊列可以重新被打開,因此要保證它們名稱的唯一性。
23. 在使用臨時性動態隊列來處理應答時,處理請求消息的應用要保證不要將應答消息設置為永久性消息。
臨時性動態隊列不能存儲永久性消息,鑒於此,對請求做出響應的應用程序必須知道接收應答的隊列是臨時性動態隊列還是永久動態隊列,請求端應用和響應端應用必須對響應消息的永久性進行協調,以保證只有非永久性消息會被放置到臨時動態隊列中。
結論:為了更好地使用MQ,我們必須遵循一定的標準和指導原則,使得我們開發出更加可靠、高效的應用程序,當然,這是從普遍意義上而言,在實際應用中需要您靈活掌握,因地制宜地選用更加適合您的配置和編程模式。
以下文章點擊率最高
Loading…