您的位置:首页 > 其它

MSMQ突破4M限制的方法

2009-08-12 16:00 218 查看
在默认情况下msmq 3.0(windows xp ,windows 2003)最大单个消息(Message size)大小4M;(包括正文和全部指定属性的消息的大小不能超过 4 MB。 来自windows 2003帮助文件的说明。)
4M的限制对于一些普通的应用来说已经足够,而且作为消息传递,报文交换,我们推荐的是不要使用超过1M大小的报文。这样可以很好的利用网络带宽,和提高系统的处理性能。

但对于一些特别少数的应用仍然存在大报文的需求,而msmq作为一个消息中间件有很多优势。所以我们还是要想办法使用他,或是扩展他的功能。 下面就我在网上和通过一些网友的帮助整理了一些突破这个4M限制方法。 1.通过修改注册表(regedit)HKLM/SOFTWARE/Microsoft/MSMQ/Parameters/ 加添一个MaxMessageSize DWORD值大小默认4M(0x00400000)最大16M(x00F00000),通过试验发现最大只能是16M左右,如果在改大,再调用程序的是否会报错




Code


using (System.Messaging.MessageQueue mq = new System.Messaging.MessageQueue(".//private$//mq3"))






{


System.Messaging.Message msg = new System.Messaging.Message();


msg.BodyStream = new FileStream("e://CodeSmithProfessional-40.msi", FileMode.Open);


mq.Send(msg);


}

2.消息分段发送,通过Message.ID,Message.CorrelationId关联,分割多个固定大小的消息.


private void SendFile(string fileName, string queuePath)






{


int i;


int count = 0;


int msgNumber = 0;


int chunkSize = 4194000;


//Open an existing queue


MessageQueue queue = new MessageQueue(queuePath);


System.Messaging.Message msg = new System.Messaging.Message();


MessageQueueTransaction t = new MessageQueueTransaction();


t.Begin();


try






{


//Open the file for reading


using (FileStream fs = File.OpenRead(fileName))






{


// while there are bytes


while ((i = fs.ReadByte()) != -1)






{


// if count has reached size, send message


if (count >= chunkSize)






{


msgNumber++;


msg.AppSpecific = msgNumber;


//Send the messsage


queue.Send(msg,t);


string nextMsgId = msg.Id;


count = 0;


//Create a new message


msg = new System.Messaging.Message();


msg.CorrelationId = nextMsgId;


}


msg.BodyStream.WriteByte((byte)i);


count++; // from the original file


}


msgNumber++;


msg.AppSpecific = msgNumber;


//Send the last message


queue.Send(msg, t);


t.Commit();


}


}


catch (Exception ex)






{


Console.WriteLine(ex);


}


finally






{


//release queue resources


queue.Close();


}


}




private void ReceiveFile(string fileName, string queuePath)






{


byte[] data;


int length;




//Open an existing queue


MessageQueue queue = new MessageQueue(queuePath);


try






{


//Open file for writing


using (FileStream fs = File.OpenWrite(fileName))






{


//Receive the first message


System.Messaging.Message msg = queue.Receive(new TimeSpan(0, 0, 0, 1));


while (msg != null)






{


//Get the Lenght of the message body stream


length = Convert.ToInt32(msg.BodyStream.Length);


//Create a buffer to hold the stream in memory


data = new byte[length];


//Read the body stream


msg.BodyStream.Read(data, 0, length);


//Write the buffer into the file


fs.Write(data, 0, length);


//Receive following message


msg = queue.Receive(new TimeSpan(0, 0, 0, 1));


}


}


}


catch (Exception ex)






{


Console.WriteLine(ex);


}


finally






{


//release queue resources


queue.Close();


}


}
3.使用BizTalk MSMQ Adapter,支持消息分段(segmentationSupport=true),前提队列必须是事务性(transactional=true),MaxMessageSize最大可以4G,试验证实一个通过passthru方式处理一个200M的文件,处理占用大量cpu和IO外,BizTalk MessageBox数据也更大400M(200M日志文件,200M数据文件)。注意:通过方法2实现的分段,在用BizTalk接收会存在问题,BizTalk不会帮组合成一个大文件处理。

4.使用BizTalk提供的一个LargeMessage api可以以编成方式实现对大报文的处理,处理方式和方法3类似。并且可以实现和BizTalk兼容。




Code
string queueFormatName = "";// args[0];
string fileName = "";// args[1];
queueFormatName = @"DIRECT=OS:ibm-t60/private$/myq";
fileName = "e://OpenbravoERP-2.35-windows-installer.exe";
LargeMessage message =
new LargeMessage(new FileStream(fileName, FileMode.Open, FileAccess.Read));

LargeMessageQueue queue =
new LargeMessageQueue(queueFormatName);

queue.Open();
try
{
queue.Send(message);
}
finally
{
queue.Close();
}

转载于:/article/4578382.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: