发布的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);
答案 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);
}
}
*上面的代码是伪代码,但该概念有效。