sqs消息大小超过256 kb

swvgeqrz  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(589)

我试图将一个json对象(序列化为字符串)发送到一个sqs队列中,该队列触发lambda。sqs消息超出了sqs的最大256 kb限制。我试图在发送之前压缩我的消息。以下是我尝试的方法:

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?

wlsrxk51

wlsrxk511#

256kb对于消息来说是巨大的,如果您发送数百万条这样的消息,那么处理它们将是非常困难的,想想sqs必须在内部执行的复制。
sqs不是一个数据库,也不是用来存储大量文本的。
我假设您的消息除了包含一些技术消息标识参数外,还包含许多业务信息。
通常这一点是因为系统设计错误。因此,您可以尝试以下操作:
考虑业务信息内容的存储。它不应该是sqs,它可以是任何东西,mongo,postgres/mysql等等,在某些情况下可能是elasticsearch甚至redis。由于应用程序在云上,aws有许多额外的存储引擎(s3、dynamodb、aurora等)。所以找一个最适合你的用例。如果您只需要某个键(路径)的文档,那么s3可能是一种选择,但是这个决定超出了这个问题的范围。
消息的“发送者”将业务相关信息存储在此存储器中,并将向sqs发送一条短消息,该短消息将包含文档上的指针(url、外键或特定于应用程序的文档id,无论什么),以便接收方在获得sqs消息后能够从存储器中获取该文档。
使用这种方法,您不需要压缩任何内容,邮件将很短。

tmb3ates

tmb3ates2#

问题是您正在发送一个gzip流,然后试图读取一个zlib流。它们是两种不同的东西。发送gzip和接收gzip,或者发送zlib和接收zlib。例如 zlib.gunzipSync 在接收端。

相关问题