2016-09-27 134 views
1

我試圖從Websphere MQ隊列讀取100 MB文件。文件應該包含約。 800.000條記錄。但是在一定的行數(通常在90.000左右)後,我只得到空的(或者可能是&#65533,這取決於我如何查看文件)。Websphere MQ,收到大量(100 MB)消息

我被告知隊列應該允許100 MB的消息。

我的代碼:

  var mqQueueManager = getMqQueueManager(ConfigurationManager.AppSettings["MQ_QueueManager"]); 
      var mqQueue = mqQueueManager.AccessQueue(mqReceiveQueueName, 
                 MQC.MQOO_INPUT_AS_Q_DEF | MQC.MQOO_FAIL_IF_QUIESCING); 

      MQGetMessageOptions gmo = new MQGetMessageOptions(); 
      gmo.Options = MQC.MQGMO_NO_WAIT; 

      for (int i = 0; i < maxMessagesToRead; i++) 
      { 
       var mqMessage = new MQMessage(); 
       mqQueue.Get(mqMessage, gmo); 

       messageTexts.Add(mqMessage.ReadString(mqMessage.MessageLength)); 
      } 

蹊蹺的代碼?或者是發送端的錯誤?

+0

是,MQ確實允許100MB的郵件大小。隊列管理器,隊列和通道所需的配置更改。你完成了嗎? – Shashi

+0

請檢查MAXMSGL屬性。它定義了最大的消息大小。此屬性存在於隊列,隊列管理器和通道級別,如@Shashi所示 – siarheib

+0

MQ設置顯示正確。是mqQueue.Get(mqMessage,gmo)是否正確或應該使用mqQueue.Get(mqMessage,gmo,maxMsgSize)重載?是mqMessage.ReadString(mqMessage.MessageLength)是否正確,或者我應該使用例如mqMessage.ReadFully(...)?還有什麼值得嘗試的? – Poppert

回答

0

目前尚不清楚要問什麼,我認爲這是問題的根源在這裏。儘管MQ可以處理最大100MB大小的消息,但問題並不在於此。

我正在嘗試從Websphere MQ隊列中讀取100 MB文件。文件 應包含約。 800.000條記錄。但一定行數 (通常約爲90.000)

在單個語句隱藏後都引用:

  • 文件
  • 隊列
  • 記錄

我相信你問的每個人都在迴應至於隊列,因此反覆保證MQ可以處理100MB的消息。但代碼似乎正在重組文件已被拆分爲一個記錄/行消息。這是一個完全不同的用例。

一次只考慮一個,MQ完全有可能來回傳遞100MB的消息。這樣做需要沿着該路徑的每個QMgr,通道和隊列都配置爲從4MB默認值MAXMSGL。不太明顯的是,如果使用線性日誌和/或消息在同步點下處理,則必須有足夠的日誌空間來包含多個100MB事務。默認的日誌範圍計數和大小不會預計100MB的消息。最後,應用程序需要配置足夠大的緩衝區,並確保不告知MQ允許截斷消息。

這種通過MQ運行文件的方法僅限於100MB以下的文件,但具有原子操作的明顯優勢 - 無論是GET/PUT整個文件還是根本沒有。沒有缺失部分,沒有任何故障,等等。這大大簡化了代碼。

第二種可能性是代碼正在重新組合已拆分爲許多消息的文件。似乎令人懷疑的是,發佈的代碼片段實際上是想將多個100MB的消息附加到對方,所以我假定它試圖從許多消息中重新組合一個文件。 (我相信高達800,000)。在這種情況下,問題是單個工作單元中可以有多少條消息。代碼片段省略了任何有意義的錯誤處理,因此我認爲同步點處理也被省略。

重新組合文件時出現的錯誤是失序消息和缺失消息。即使是最簡單的基於MQ的文件移動器,每個文件使用多個消息也需要使用同步點來確保整個文件作爲一個單元發送或接收。但MQ不會在單個工作單元中預計800,000條消息,因此您需要調整日誌範圍MAXUMSGS以做更多的事情而不是一件小事。

當然,移動文件並保證它們在被分割成許多消息時的完整性並不是微不足道的,當所有的排列被考慮時,結果看起來很像MQ Managed File Transfer。

再回到這個問題,如果該文件是在消息,並截斷消息的API選項上搬運未設置,則沒有什麼的MQ API中,經過一定的行數會影響消息或消息長度。在這種情況下,解釋讓垃圾超過某一點的唯一方法是發送應用程序發送它。 (例如,分配100MB緩衝區,填充50MB,然後發送100MB消息。)

但是,如果文件被拆分成代碼中顯示的許多消息,則必須執行上述調整。其中包括將MAXUMSGS的值增加到大於800,000的值(doc link),並確保主要日誌擴展盤區和輔助日誌擴展盤區中有足夠的空間來容納幾個大型工作單元。詳情請參閱Calculating the size of the log

順便說一句,你可能還希望每次重置MQGMO因爲在Overview該對象指出,它既是輸入輸出。

修改後的代碼看起來會像這樣:

  MQGetMessageOptions gmo = new MQGetMessageOptions(); 

      for (int i = 0; i < maxMessagesToRead; i++) 
      { 
       var mqMessage = new MQMessage(); 
       gmo.Options = MQC.MQGMO_NO_WAIT; 
       mqQueue.Get(mqMessage, gmo); 
+0

是的,這是一個傳遞的單個消息。似乎問題出在發送端,而不是在接收消息的代碼中(上面)。感謝您的解釋! – Poppert