• MSMQ突破4M限制的方法 [ZT]


    在默认情况下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左右,如果在改大,再调用程序的是否会报错

    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(0001));
                        
    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(0001));
                        }

                    }

                }

                
    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兼容。


    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();
                }
  • 相关阅读:
    myfocus之焦点图
    win7磁盘分区工具
    java线程两种创建方式的区别与模拟买票情景
    jsp指令与动作
    Cookie记住登陆账号和密码
    jsp+javabean实现简单的用户登陆
    jsp简单登陆实现
    strut2 文件上传完整案例
    poi 导出excel文件
    poi excel文件的导入
  • 原文地址:https://www.cnblogs.com/RobotTech/p/980612.html
Copyright © 2020-2023  润新知