检查SQS消息批量的大小

时间:2016-11-08 14:45:48

标签: java amazon-web-services amazon-sqs

发布的SQS消息的大小有limits。单条消息不能大于256 KB,一批消息(最多10条)也不能超过256 KB。将消息添加到集合以便稍后发布到SQS队列时,如何跟踪消息大小以确保我的请求保持在限制之下?

我已经查看了获取size of an object的方法,并且我知道在调用sendMessageBatch()后我可以使用失败消息的ID。我不觉得其中任何一个都是非常好的解决方案,因为对象本身的大小忽略了消息的开销数据(我认为也很重要),我真的不想简单地管理失败的消息因为批次太大了。我真的不希望我的信息那么大,但你永远不会知道。

要批量发送的代码段:

List<SendMessageBatchRequestEntry> entries = new LinkedList<>();

然后循环:

SendMessageBatchRequestEntry entry = new SendMessageBatchRequestEntry();

entry.setMessageBody(gson.toJson(message));
entry.setMessageAttributes(attributes);             
entry.setId(messageId);

// How to make sure `entry` is not larger than 256 KB, and how to
// make sure adding this entry won't cause the batch to exeed 256 KB?

entries.add(entry);

最后:

client.sendMessageBatch(queueUrl, entries);

2 个答案:

答案 0 :(得分:1)

根据AWS SQS Batch说明,

  

您在一个邮件中发送的所有邮件的总大小    static - content - css - fonts.css - fonts - rt-icons-23dab.eot - rt-icons-2d41d.eot - rt-icons-23dab.ttf - rt-icons-23dab.woff - rt-icons-23dab.svg 调用不能超过262,144字节(256 KB)。

根据此,SendMessageBatch调用不应超过256KB。在查看代码段时,您使用了名为SendBatchMessage的{​​{1}}对象。所有列表对象都可以用Java序列化。请参阅this answer

通过序列化可以很好地估计对象的大小。它的代码如下。

List

通过这个,您可以获得条目LinkedList的大致字节大小。之后,您可以在添加新的条目对象后检查条目列表是否超过256Kb。如果是这样,则丢弃该条目对象并使用先前的条目调用SendBatchMessage对象为SQS。代码段如下所示。

entries

答案 1 :(得分:-1)

这是一种更为简单的方法,而不是重复浪费时间来序列化整个消息列表。取而代之的是,从正文中获取一个基本的值,说明属性和ID,我在这里允许在maxBatchMessageSize中花费大约6k的开销,但是如果我可以计算属性的大小,我会得到更接近的数字;

int sqsBatchSize = 10;
int maxBatchMessageSize = 250000;
int currentBatchSize = 0;

private void sendMessage(Object message) {
    String msgString = gson.toJson(message);
    int size = msgString.length() + messageId.length() + "whatever else if a factor".length();
    if (currentBatchSize + size > maxBatchMessageSize || sqsBatchSize == entries.size()) {
        client.sendMessageBatch(queueUrl, entries);
        entries.clear();
        currentBatchSize = 0;
    }
    SendMessageBatchRequestEntry entry = new SendMessageBatchRequestEntry();
    entry.setMessageBody(gson.toJson(message));
    entry.setMessageAttributes(attributes);
    entry.setId(messageId);
    entries.add(entry);
    currentBatchSize += size;
}

public void close() {
    if(!entries.isEmpty()) {
        client.sendMessageBatch(queueUrl, entries);
    }
}

*上面的代码是伪代码,但该概念有效。