簡體   English   中英

將消息異步放在WebSphere MQ隊列上

[英]Put message async on WebSphere MQ queue

我正在嘗試將持久消息放入WebSphere MQ隊列,但是這些消息需要異步放入。 我似乎能夠得到異步工作的唯一方法是,如果消息和非持久(由我的意思是, putSuccessCount等於穿上消息數MQAsyncStatus ,其他時間是零)。 下面的代碼概述了我想做的事情:

import com.ibm.mq.MQAsyncStatus;
import com.ibm.mq.MQDestination;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQPutMessageOptions;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.constants.MQConstants;

public class MQPutTest extends TestCase{

    private static Logger log = Logger.getLogger(MQPutTest.class);

    public void testPut() throws Exception{

        Hashtable<String, Object> props = new Hashtable<String, Object>();
        props.put(MQConstants.CHANNEL_PROPERTY, "my_channel");
        props.put(MQConstants.PORT_PROPERTY, 1414);
        props.put(MQConstants.HOST_NAME_PROPERTY, "localhost");

        String qManager = "my_queue_manager"; 
        MQQueueManager qMgr = new MQQueueManager(qManager, props);

        int openOptions = MQConstants.MQOO_OUTPUT | MQConstants.MQOO_INPUT_AS_Q_DEF;

        MQDestination queue = qMgr.accessQueue("my_queue", openOptions);

        MQPutMessageOptions pmo = new MQPutMessageOptions();
        pmo.options = MQConstants.MQPMO_ASYNC_RESPONSE;

        MQMessage message = new MQMessage();
        message.format = MQConstants.MQFMT_STRING;
        message.writeString("test message");
        queue.put(message, pmo);

        queue.close();
        MQAsyncStatus asyncStatus = qMgr.getAsyncStatus();
        qMgr.disconnect();
    }
}

我將看到的大量郵件歸因於性能提高,原因是該隊列設置為非持久性,而不是將消息置於異步狀態。 我已經在MQ資源管理器中的隊列擴展屬性中將默認的put響應類型設置為Asynchronous,這沒有任何效果。

任何幫助,將不勝感激。

如果可以丟失一條或兩條消息,則可以將消息添加到內部發送隊列中,例如

ExecutorService service = Executors.newSingleThreadedExecutor();

// build you message here

// add the message to be sent asynchronously.
service.execute(new Runnable() {
    public void run() {
         queue.put(message, pmo);
    }
});

進程死后,隊列中的所有消息都將丟失。

根據問題中的評論,WMQ沒有“持久隊列”的概念(因此,我更改了帖子標題)。 用於持久性的隊列屬性在任何方面都不會改變QMgr處理隊列或隊列中任何消息的方式。 它所做的只是告訴程序員,如果程序員未能明確設置該值,則使用哪個持久性選項。 給定消息是否持久,取決於將消息首次放入隊列時MQMD是否指定持久性。 任何隊列可以包含任意組合的持久性消息和非持久性消息。

具體來說,他發布的代碼片段未使用message.setPersistence()指定持久性,因此它將繼承隊列的默認值。 這又取決於從queue屬性繼承的值。 在任何情況下,隊列屬性設置都不會覆蓋應用程序中的顯式設置

因此,您看到的性能差異確實很可能反映了隊列的DEFPSIST屬性的設置,但這並不意味着異步puts無法正常工作。 請記住,異步放入不會以任何方式減少將消息放入隊列所花費的時間。 QMgr具有相同的代碼路徑來持久化消息,無論是否同步。 不同之處在於您的應用不再等待QMgr完成其工作。 完全有可能,當您要求更新MQAsyncStatus ,WMQ尚未編寫任何消息。 如果它們全部在一個工作單元中,則更有可能發生這種情況,因為WMQ直到COMMIT處理完成后才會返回所有消息的狀態。 除非您顯式調用COMMIT ,否則在關閉隊列時會發生這種情況。

您可以通過在COMMITCLOSE之后幾秒鍾每秒重復qMgr.getAsyncStatus()調用來驗證這一點。 您應該看到第一個沒有成功返回任何消息,但最終您可以解釋所有消息。

順便說一句,關於消息是否持久的問題幾乎應該總是在您的代碼中處理 消息持久性通常是作為業務需求而派生的,該業務需求是在應用程序設計中捕獲的。 因此,項目經理和開發人員有責任確保滿足要求。 可靠地確保滿足要求的唯一方法是應用程序顯式調用setPErsistence() 否則,應用程序將使用隊列的DEFPSIST屬性中的值隱式調用setPersistence() 那么,為什么要麻煩在API中允許這種默認設置呢? 因為在一些合法的情況下,需要在運行時更改持久性。 編寫應用程序以有意采用默認值,並在每個工作單元完成此操作后重新打開隊列。 在所有其他情況下,應在程序或托管對象中設置持久性。

最后,如果將10,000條消息放在一個工作單元下,則另一個原因是您會收到一條響應,指出沒有成功發送消息,這是因為缺少日志空間或未設置可調參數來適應負載。 例如,如果MAXUMSGS設置為小於10,000,則整個事務將回滾。 另一方面,如果MAXUMSGS設置正確,但是主日志和輔助日志的大小和數量不足以容納事務中的數據量,則整個事務將再次回滾。 您應該以COMMIT間隔進行操作,因為最佳值取決於與隊列和日志緩沖區大小相關的消息大小。 一旦超出了可以在單個寫入操作中優化的數據量,其他消息實際上就會降低性能。 當人們將10,000條消息放到一個工作單元中時,性能幾乎就不存在了,而是因為這是他們適當的恢復單元,而相應的性能損失卻是恢復要求的次要條件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM