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