3

根据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

4

1 回答 1

9

.NET 存储客户端库 (Microsoft.WindowsAzure.StorageClient.dll) 对队列消息内容进行 base-64 编码,因此当您使用 .NET 客户端库时,有效限制为 8192 * .75 = 6144字节。(这是因为 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();
    }
}
于 2011-07-06T16:03:07.213 回答