【问题标题】:Maximum CloudQueueMessage payload size issue最大 CloudQueueMessage 有效负载大小问题
【发布时间】:2011-09-29 13:57:05
【问题描述】:

根据MSDN,消息有效负载可以扩展到8KB(8192字节):

AddMessage 方法将消息添加到队列的后面。 一条消息的大小可能高达 8 KB。其内容必须采用可使用 UTF-8 编码的格式。

但是,当将消息添加到队列中时,我收到了消息的异常,这些消息的有效负载应该小于 8192 字节,魔法区域似乎在 6500 字节左右。我发送的数据是纯字符串,其大小通过.Length 成员和从其中检索它们的源发送的长度进行验证(CRLF 分隔符有一个恒定的 2 字节差异)。

所以我的问题有两个:

1) 是否有任何隐藏数据附加到消息负载中,会使其大小膨胀或导致这种奇怪的行为? (例如对整个对象应用的限制,而不仅仅是它的有效负载,即使这样,它怎么能占到每条消息 1.5KB?)

2) 我如何可靠地检查负载确实低于 8192?

还有一些额外的信息:我正在使用带有 VS 2010 Ultimate 的 Azure SDK 1.4,使用 SQLExpress(我认为是 2008 年)通过计算和存储模拟器(我还没有部署这个应用程序)运行。

还通过代码确认最大大小为 8192 字节(在某些额外系统强加限制的情况下):

Trace.WriteLine("Max Queue Message Size: " + CloudQueueMessage.MaxMessageSize, "CloudQueueMessage");

CloudQueueMessage:最大队列消息大小:8192

【问题讨论】:

    标签: c# azure-storage azure-queues


    【解决方案1】:

    .NET 存储客户端库 (Microsoft.WindowsAzure.StorageClient.dll) 对队列消息内容进行 base-64 编码,因此当您使用.NET 客户端库。 (这是因为 base 64 编码增加了 1/3 的开销。)

    (请注意,您没有到 base 64 编码。恰好是这个库确保队列消息的内容可以安全地嵌入到 XML 中的方式,这是要求队列服务放置在消息上。)


    编辑:以下是使用 Microsoft.WindowsAzure.StorageClient.Protocol 命名空间将原始文本(不是 base 64 编码)放入队列消息(并随后检索它)的示例代码:

    using System;
    using System.Net;
    using Microsoft.WindowsAzure;
    using Microsoft.WindowsAzure.StorageClient;
    using Microsoft.WindowsAzure.StorageClient.Protocol;
    
    class Program
    {
        static void Main(string[] args)
        {
            var q = CloudStorageAccount.Parse("UseDevelopmentStorage=true").CreateCloudQueueClient().GetQueueReference("testqueue");
            q.CreateIfNotExist();
    
            var req = QueueRequest.PutMessage(new Uri(q.Uri, q.Name + "/messages"), 30, null);
            var body = QueueRequest.GenerateMessageRequestBody("hello world");
            req.ContentLength = body.Length;
            q.ServiceClient.Credentials.SignRequest(req);
            using (var stream = req.GetRequestStream())
            {
                stream.Write(body, 0, body.Length);
                stream.Close();
            }
            req.GetResponse();
    
            req = QueueRequest.GetMessages(new Uri(q.Uri, q.Name + "/messages"), 30, 32, null);
            q.ServiceClient.Credentials.SignRequest(req);
            using (var response = (HttpWebResponse)req.GetResponse())
            {
                using (var msgResponse = QueueResponse.GetMessages(response))
                {
                    foreach (var msg in msgResponse.Messages)
                    {
                        Console.WriteLine("MESSAGE: " + msg.Text);
                        q.DeleteMessage(msg.Id, msg.PopReceipt);
                    }
                }
            }
    
            q.Delete();
        }
    }
    

    【讨论】:

    • 那么我该如何避免使用 base64 编码呢?我需要使用不同的库/消息构造方法吗?
    • 编辑了我的答案以包含一个示例。
    猜你喜欢
    • 2017-08-23
    • 1970-01-01
    • 2011-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多