本文介绍了如何通过QuickNode Streams的数据压缩功能来降低区块链数据的成本。通过启用压缩,可以在已经过滤的数据基础上,进一步节省高达90%的成本。文章详细说明了如何在QuickNode控制台中启用GZIP压缩,并提供了使用Node.js Express服务器处理压缩数据的示例代码,包括自动解压和手动解压两种方法。
QuickNode Streams 已经通过过滤区块链数据,只保留你需要的部分来帮助你降低成本。但是,如果你能进一步降低这些成本呢?启用压缩后,你可以在已过滤的数据上额外节省高达 90% 的成本,而无需改变你的核心工作流程。
本指南将引导你完成为 Streams 启用压缩、在你的应用程序中实现解压缩,以及通过实际示例计算你潜在的成本节省。
gzip
数据,包括自动和手动方法QuickNode Webhooks
喜欢 Streams 提供的实时数据功能吗?查看我们的新产品 Webhooks。它建立在 Streams 之上,并在简化的、易于使用的界面中提供相同的过滤和压缩功能。Webhooks 专门为简单、事件驱动的通知而设计,提供了一种更快的方式将实时数据发送到你的 HTTP endpoints,而无需 Streams 的完整复杂性。
通过 Streams,你已经具有过滤功能,可以通过仅接收你需要的链上数据来减少 payload 大小。当你将压缩添加到已过滤的 Streams 时,成本节省将变得更加显着。
让我们看一个实际的例子,使用单个以太坊区块中 token transfers 的 payload 大小:
注意: 所有数据大小均为估计值,可能因处理的实际数据而异。
由于以太坊上每月大约有 220,000 个区块,因此成本和带宽节省可能非常可观:
方法 | 每月数据大小 |
---|---|
未过滤的原始数据 | 218 GB |
过滤 | 135 GB |
过滤 + 压缩 | 13 GB |
在本指南中,我们将为具有 webhook destination 的 Stream 启用压缩,并设置一个 Node.js Express 服务器来处理压缩的数据。
你只需在 QuickNode 仪表板中单击一下即可启用压缩。
注意: 压缩功能适用于 Webhook 和 S3 destinations。
启用压缩后,QuickNode 将开始以压缩的 gzip 格式发送此 Stream 的所有 webhook payloads。 webhook 还将包括 header Content-Encoding: gzip
,以表明 payload 已压缩。因此,你的应用程序应检查此 header 以确定是否需要解压缩。
现在让我们构建将接收压缩数据的 Node.js Express 服务器。你的服务器启动并运行后,我们将完成 Stream 的创建。
要处理压缩数据,你需要在应用程序中对其进行解压缩。在此示例中,我们将使用 Node.js Express 服务器来接收压缩数据并对其进行解压缩。
创建一个新的 Node.js 项目:
mkdir streams-compression-example
cd streams-compression-example
npm init -y
安装服务器所需的依赖项:
npm install express
下面的代码设置了一个基本的 Express 服务器,以演示如何处理来自 Streams 的压缩 payloads。它包括两个不同的路由:
/webhook/auto
: 这是主要路由。它使用 express.raw({ inflate: true })
中间件,该中间件会自动检测 Content-Encoding: gzip
header 并解压缩 request body。这使得 payload 可以直接在 req.body
中使用,就像它从未被压缩过一样。
/webhook/manual
: 这个可选路由向你展示了如果你需要更好地控制该过程,如何手动处理解压缩。我们将在本指南的稍后部分添加此路由的代码。
创建一个服务器文件(app.js
)并添加以下代码:
app.js
const express = require("express");
const zlib = require("zlib");
const app = express();
// Helper function to convert bytes to kilobytes
// 辅助函数,将字节转换为千字节
const bytesToKB = (bytes) => (bytes / 1024).toFixed(2);
// Route 1: Auto-inflate enabled (Express handles decompression)
// 路由 1:启用自动解压(Express 处理解压缩)
app.post(
"/webhook/auto",
express.raw({ inflate: true, type: "*/*", limit: "10mb" }), // Adjust limit as needed
// 根据需要调整限制
(req, res) => {
console.log("\n=== AUTO-INFLATE ROUTE ===");
console.log("Headers:", req.headers);
// req.body is already decompressed
// req.body 已经被解压缩
const decompressedSize = req.body.length;
console.log(
`Decompressed payload size: ${bytesToKB(
decompressedSize
)} KB (${decompressedSize} bytes)`
);
try {
const data = JSON.parse(req.body.toString());
console.log("Payload data:", data);
res.status(200).json({
status: "OK",
method: "auto-inflate",
decompressedSizeKB: bytesToKB(decompressedSize),
});
} catch (err) {
console.error("Parse error:", err);
res.status(400).send("Invalid JSON");
}
}
);
// Route 2: Manual decompression (inflate disabled)
// 路由 2:手动解压缩(禁用解压)
// This route is optional and shows how to manually decompress if needed
// 此路由是可选的,展示了如果需要如何手动解压缩
// Code will be added later in this guide
// 代码将在本指南的稍后部分添加
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Webhook server listening on port ${PORT}`);
console.log(`Test the endpoints:`);
console.log(` - http://localhost:${PORT}/webhook/auto (auto-inflate)`);
console.log(` - http://localhost:${PORT}/webhook/manual (manual decompression)`);
});
启动你的服务器:
node app.js
要使用 Streams 测试你的服务器,你需要将其暴露给互联网。你可以使用 ngrok 之类的工具,也可以将其部署到云服务。对于本地测试,请在新终端窗口中运行以下命令:
ngrok http 3000 # or other port if you changed it
# 如果你更改了端口,则使用其他端口
这会将你的服务器暴露给互联网上的一个随机端口。复制转发 URL(例如,https://xxxx.ngrok.io
)并通过在末尾添加 /webhook/auto
将其粘贴到 Streams destination URL 中。(例如,https://xxxx.ngrok.io/webhook/auto
)
设置 destination URL 后,你可以通过将示例 payload 发送到你的 Stream 来测试你的服务器。
首先,通过单击 QuickNode 仪表板中的 Check Connection 按钮来检查连接。然后,通过单击 Send Payload 按钮将示例 payload 发送到你的 Stream。这将触发对你的服务器的 webhook 调用。
服务器将记录 headers、解压缩的 payload 大小和已解析的 JSON 数据。由于 payload 已自动解压缩,因此你可以通过检查请求中的 content-length
header 来检查实际压缩的 payload 大小(以字节为单位)。在发送测试 payload 后,检查运行 ngrok 的终端,你将看到如下内容:
如你所见,服务器会自动解压缩 payload,你可以直接在 req.body
中访问数据。完毕。
在 Express 中间件中将 inflate
选项设置为 true
会自动解压缩 payload。但是,如果你出于任何原因想要手动解压缩 payload,则可以使用 zlib
模块来执行此操作。这是一个如何操作的示例。只需将此路由添加到你现有的 app.js
文件中。
此代码段将 /webhook/manual
路由添加到你的服务器。与自动解压路由不同,此路由处理原始 request body。它将传入的压缩数据收集到缓冲区中,检查 content-encoding
header,如果是 gzip
,则使用 Node.js 的内置 zlib.gunzip
方法来解压缩 payload。
此方法还计算并记录压缩率,向你显示压缩数据和解压缩数据之间的确切大小差异。
app.js 继续
// Continue from the previous app.js code snippet
// 从之前的 app.js 代码段继续
// Route 2: Manual decompression (inflate disabled)
// 路由 2:手动解压缩(禁用解压)
// This route is optional and shows how to manually decompress if needed
// 此路由是可选的,展示了如果需要如何手动解压缩
app.post("/webhook/manual", (req, res) => {
console.log("\n=== MANUAL DECOMPRESSION ROUTE ===");
console.log("Headers:", req.headers);
// Store the content-encoding header and then delete it
// 存储 content-encoding header,然后删除它
// to prevent Express from throwing an error
// 以防止 Express 抛出错误
const contentEncoding = req.headers["content-encoding"];
delete req.headers["content-encoding"];
let chunks = [];
req.on("data", (chunk) => {
chunks.push(chunk);
});
req.on("end", () => {
const compressedBuffer = Buffer.concat(chunks);
const compressedSize = compressedBuffer.length;
console.log(
`Compressed payload size: ${bytesToKB(
compressedSize
)} KB (${compressedSize} bytes)`
);
// Check if content was compressed
// 检查内容是否被压缩
if (contentEncoding === "gzip") {
zlib.gunzip(compressedBuffer, (err, decompressedBuffer) => {
if (err) {
console.error("Decompression error:", err);
return res.status(500).send("Decompression error");
}
const decompressedSize = decompressedBuffer.length;
console.log(
`Decompressed payload size: ${bytesToKB(
decompressedSize
)} KB (${decompressedSize} bytes)`
);
const compressionRatio = (
(1 - compressedSize / decompressedSize) *
100
).toFixed(1);
console.log(`Compression ratio: ${compressionRatio}% reduction`);
try {
const data = JSON.parse(decompressedBuffer.toString());
console.log("Payload data:", data);
res.status(200).json({
status: "OK",
method: "manual-decompression",
compressedSizeKB: bytesToKB(compressedSize),
decompressedSizeKB: bytesToKB(decompressedSize),
compressionRatio: `${compressionRatio}%`,
});
} catch (err) {
console.error("Parse error:", err);
res.status(400).send("Invalid JSON");
}
});
}
});
req.on("error", (err) => {
console.error("Request error:", err);
res.status(500).send("Request error");
});
});
之后,你可以通过将压缩的 payload 发送到 /webhook/manual
来测试手动解压缩路由。日志输出将显示压缩大小、解压缩大小和压缩率,如下所示。
在测试压缩后,你现在可以通过单击 QuickNode 仪表板中的 Create a Stream 按钮来最终确定并激活你的 Stream,以接收压缩的实时数据。
你已成功学习如何为 QuickNode Streams 启用压缩以及如何在 Express.js 应用程序中处理压缩数据。实现非常简单,只需几行代码即可处理解压缩,而节省是立竿见影且可观的。
如果你有任何疑问,请直接 联系我们。如果你有任何想法或建议,例如新的 destinations、功能、指标或数据集,你希望我们支持。
此外,请在 Twitter 上关注我们,并加入我们的 Discord 和 Telegram 公告频道,以随时了解最新信息。
如果你有任何反馈或对新主题有任何要求,请 告诉我们。我们很乐意听取你的意见。
- 原文链接: quicknode.com/guides/qui...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!