【问题标题】:SQS Message Size Exceeding 256 kBSQS 消息大小超过 256 kB
【发布时间】:2021-03-20 12:52:11
【问题描述】:

我正在尝试将 json 对象(序列化为字符串)发送到触发 lambda 的 SQS 队列中。 SQS 消息超出了 SQS 的最大 256 kB 限制。我试图在发送之前对我的消息进行 gzip 压缩。以下是我的尝试:

public static String compress(String str) throws Exception {
        System.out.println("Original String Length : " + str.length());
        ByteArrayOutputStream obj=new ByteArrayOutputStream();
        GZIPOutputStream gzip = new GZIPOutputStream(obj);
        gzip.write(str.getBytes("UTF-8"));
        gzip.close();
        String base64Encoded = Base64.getEncoder().encodeToString(obj.toByteArray());
        System.out.println("Compressed String length : " + base64Encoded.length());
        return base64Encoded;
    }

此 SQS 队列触发的 lambda 是基于 nodejs 的 lambda,我需要在其中解压缩和解码此消息。我尝试使用 nodejs 中的 zlib 库来解压缩和解码我的消息,如下所示:

exports.handler = async (event, context) => {
  let msg = null
  event.Records.forEach(record => {
    let { body } = record;
    var buffer = zlib.inflateSync(new Buffer(body, 'base64')).toString();
    msg = JSON.parse(JSON.parse(JSON.stringify(buffer.toString(), undefined, 4)))
  });
}

执行时出现以下错误:

{
    "errorType": "Error",
    "errorMessage": "incorrect header check",
    "code": "Z_DATA_ERROR",
    "errno": -3,
    "stack": [
        "Error: incorrect header check",
        "    at Zlib.zlibOnError [as onerror] (zlib.js:180:17)",
        "    at processChunkSync (zlib.js:429:12)",
        "    at zlibBufferSync (zlib.js:166:12)",
        "    at Object.syncBufferWrapper [as unzipSync] (zlib.js:764:14)",
        "    at /var/task/index.js:12:19",
        "    at Array.forEach (<anonymous>)",
        "    at Runtime.exports.handler (/var/task/index.js:10:17)",
        "    at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"
    ]
}

谁能告诉我如何以更好的方式解决这个问题?有没有更好的方法来压缩java中的字符串?有没有更好的方法来解压、解码和解析nodejs中的json?

【问题讨论】:

  • 为什么不将String 存储到S3 中,然后在SQS 消息中分享URL 以供Lambda 取货?如果您的消息超出了256KB 作为安全墙,这是最好的方法。没有算法可以在 100% 的时间内压缩这么多。建议您在生产环境中设置安全墙,以减轻某些消息(假设 10% 超过 256KB)

标签: java node.js aws-lambda amazon-sqs zlib


【解决方案1】:

256Kb 的消息是巨大的,如果像这样发送数百万条消息,将很难全部处理,请考虑 SQS 必须在内部进行的复制。

SQS 不是数据库,它并不意味着存储大量文本。

我假设你的消息除了一些技术消息识别参数之外还包含很多业务信息。

这通常指向系统的错误设计。因此,您可以尝试以下方法:

  1. 考虑存储业务信息的内容。它不应该是 SQS,它可以是任何东西,Mongo、Postgres/MySQL 等等,在某些情况下可能是 ElasticSearch 甚至是 Redis。由于应用程序位于云上,因此 aws 具有许多额外的存储引擎(S3、DynamoDB、aurora 等)。因此,请找到最适合您的用例的那个。如果您只需要某个键(路径)的文档,那么 S3 可能是要走的路,但这个决定超出了这个问题的范围。

  2. 消息的“发送者”将业务相关信息存储在此存储中,并将向 SQS 发送一条短消息,该短消息将包含文档上的指针(url、外键或应用程序特定文档 ID,等等)这样接收方就可以在收到 SQS 消息后从存储中获取该文档。

使用这种方法,您无需压缩任何内容,消息会很短。

【讨论】:

    【解决方案2】:

    问题是您正在发送 gzip 流,然后尝试读取 zlib 流。他们是两个不同的东西。要么发送 gzip 并接收 gzip,要么发送 zlib 并接收 zlib。例如。 zlib.gunzipSync 在接收端。

    【讨论】:

      猜你喜欢
      • 2014-06-06
      • 1970-01-01
      • 2023-01-24
      • 2017-03-22
      • 2019-05-31
      • 2015-09-09
      • 1970-01-01
      • 2021-10-04
      • 2013-06-27
      相关资源
      最近更新 更多