java - 检查 SQS 消息批处理的大小

标签 java amazon-web-services amazon-sqs

limits关于发布的 SQS 消息的大小。单条消息不能大于 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);

最佳答案

根据 AWS SQS Batch 注释,

The total size of all messages that you send in a single SendMessageBatch call can't exceed 262,144 bytes (256 KB).

据此,SendBatchMessage 调用不应超过 256KB。在查看您的代码片段时,您使用了一个名为 entriesList 对象。所有列表对象在 Java 中都是可序列化的。参见 this answer .

您可以通过序列化来很好地估计对象的大小。下面给出了它的代码。

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(entries);
oos.close();
System.out.println(baos.size());

有了这个,您可以获得条目 LinkedList 的近似大小(以字节为单位)。之后,您可以在添加新条目对象后简单地检查条目列表是否超过 256Kb。如果是这样,则丢弃条目对象并使用先前的条目对象调用 SendBatchMessage 到 SQS。代码片段如下。

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

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

    entries.add(entry);
    if ( getObjectSize(entries) > 262144) {
      entries.remove(entry);
      client.sendMessageBatch(queueUrl, entries);
    } else {
      //add another entry to the entries List 
    }

  private static int getObjectSize(List object) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(object);
    oos.close();
    return baos.size();
  }

关于java - 检查 SQS 消息批处理的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40489815/

相关文章:

java - Eclipse 找不到我已经运行的 Android 模拟器

java - 对包中的类进行分组

amazon-web-services - AWS SAM : How to create an S3 bucket with an already existing encryption key using SAM

amazon-web-services - 谁删除了 S3 存储桶中的文件?

python - (python/boto sqs) UnicodeDecodeError : 'ascii' codec can't decode byte 0xc3 in position 5: ordinal not in range(128)

amazon-web-services - Amazon SQS FIFO 队列 - 总共获得 10 条消息但仍强制执行 MessageGroupId 计数?

java - 无法从 EMR 中运行的 Spark 应用程序删除 AWS SQS 消息

java - 使用jquery调用web服务

java - 在 for 循环内声明变量以及 print 语句时出错

java - 使用 CloudFormation 创建 Elastic Beanstalk "Hello, world."Java env/app