利用数据压缩优化 Streams 带宽

本文介绍了如何使用 Quicknode Streams 的压缩功能来减少区块链数据的带宽和有效载荷大小。通过启用压缩,用户可以在过滤后的数据上减少高达 90% 的带宽,而无需更改核心工作流程。文章提供了启用压缩的步骤、在 Node.js Express 服务器中实现解压缩的方法,以及实际示例说明带宽减少的效果。

概述

Quicknode Streams 通过过滤帮助你仅接收你需要的相关区块链数据。启用压缩后,你可以在不改变核心工作流程的情况下,将过滤后的数据的带宽和交付有效载荷大小减少高达 90%。

本指南将引导你完成为 Streams 启用压缩、在应用程序中实施解压缩以及通过实际示例了解带宽减少的过程。

你将做什么

  • 了解 Streams 过滤和压缩如何减少带宽和交付有效载荷大小
  • 为你的 Streams 目标地启用压缩
  • 在 Node.js Express 服务器中处理压缩的 gzip 数据,包括自动和手动方法

你将需要什么

  • 一个具有付费计划的 Quicknode 账户
  • JavaScript 的基本知识
  • ngrok 或类似的工具,用于将你的本地服务器暴露给互联网(用于测试目的)

Quicknode Webhooks

喜欢 Streams 提供的实时数据功能吗?查看我们的新产品 Webhooks。它构建在 Streams 之上,并在简化的、易于使用的界面中提供预定义的过滤器模板和压缩功能。Webhooks 专门为 简单、事件驱动的通知 而设计,无需 Streams 的完整复杂性,即可更快地将实时数据发送到你的 HTTP 端点

Streams 中的区块链数据压缩

通过 Streams,你拥有过滤功能,可以仅接收你需要的相关链上数据。当你向过滤后的 Streams 添加压缩时,你可以显著减少带宽和交付有效载荷大小。

  1. Streams 过滤:仅传递你关心的数据
  2. Gzip 压缩:进一步将过滤后的数据有效载荷减少高达 90%

让我们看一个真实世界的例子,使用单个 Ethereum 区块 内的 token 转移的有效载荷大小:

  • 未过滤的原始数据区块 中所有交易的原始数据约为 990 KB。
  • 使用 Streams 过滤:通过使用 Streams 过滤仅解码的 ERC-20 token 转移,你可以将有效载荷大小减少到约 617 KB——仅通过过滤即可减少近 38% 的数据。
  • 使用过滤和压缩:通过在过滤后的 上启用压缩,数据缩小到仅约 62 KB。

注意:所有数据大小均为估计值,可能因处理的实际数据而异。

Streams 过滤和压缩

由于 Ethereum 上每月大约有 220,000 个区块,因此带宽和交付有效载荷大小的减少可能是巨大的:

方法 每月数据大小
未过滤的原始数据 218 GB
过滤 135 GB
过滤 + 压缩 13 GB

如何在 Streams 中使用压缩

在本指南中,我们将为具有 webhook 目标地的 Stream 启用压缩,并设置一个 Node.js Express 服务器来处理压缩的数据。

步骤 1:在你的 Stream 中启用 GZIP 压缩

你只需在 Quicknode 仪表板 中单击一下即可启用压缩。

  1. 导航到你的 Quicknode 仪表板 中的 Streams 部分
  2. 选择你要修改的 Stream 或创建一个新的 Stream
  3. (可选)在“Stream 数据集”部分中过滤你的 Stream。随意使用模板(即,解码的 ERC20 转移)或创建一个自定义模板
  4. 在 Stream 的“目标地”部分中,从“有效载荷压缩”下拉菜单中选择“Gzip”
  5. 检查“估计数据量”如何变化以反映启用压缩后的大小减少

注意:压缩功能适用于 Webhook 和 S3 目标地。

启用压缩后,Quicknode 将开始以压缩的 gzip 格式发送此 Stream 的所有 webhook 有效载荷。Webhook 还将包括 Content-Encoding: gzip,以表明有效载荷已压缩。因此,你的应用程序应检查此以确定是否需要解压缩。

现在,让我们构建将接收压缩数据的 Node.js Express 服务器。我们将在你的服务器启动并运行后完成 Stream 的创建。

步骤 2:设置你的应用程序来处理压缩数据

要处理压缩数据,你需要在应用程序中解压缩它。在此示例中,我们将使用 Node.js Express 服务器来接收压缩数据并解压缩它。

2.1 创建一个 Node.js 项目

创建一个新的 Node.js 项目:

mkdir streams-compression-example
cd streams-compression-example
npm init -y

2.2 安装依赖项

安装服务器所需的依赖项:

npm install express

2.3 创建一个服务器

以下代码设置了一个基本的 Express 服务器,以演示如何处理来自 Streams 的压缩的有效载荷。它包括两个不同的路由:

  • /webhook/auto:这是主要路由。它使用 express.raw({ inflate: true }) 中间件,该中间件会自动检测 Content-Encoding: gzip 并解压缩请求主体。这使得有效载荷可以直接在 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)`);
});

2.4 运行服务器

启动你的服务器:

node app.js

2.5 暴露你的服务器

要使用 Streams 测试你的服务器,你需要将其暴露给互联网。你可以使用 ngrok 之类的工具或将其部署到云服务。对于本地测试,请在新终端窗口中运行以下命令:

ngrok http 3000 # or other port if you changed it
# 如果你更改了端口,则使用其他端口

这会将你的服务器暴露给互联网上的一个随机端口。复制转发 URL(例如,https://xxxx.ngrok.io)并通过在末尾添加 /webhook/auto 将其粘贴到 Streams 目标 URL 中。(例如,https://xxxx.ngrok.io/webhook/auto

2.6 测试服务器

设置目标 URL 后,你可以通过将示例有效载荷发送到你的 Stream 来测试你的服务器。

首先,通过单击 Quicknode 仪表板 中的“检查连接”按钮来检查连接。然后,通过单击“发送有效载荷”按钮将示例有效载荷发送到你的 Stream。这将触发对你的服务器的 webhook 调用。

服务器将记录、解压缩的有效载荷大小和已解析的 JSON 数据。由于 有效载荷 是自动解压缩的,因此你可以通过检查请求中的 content-length 来检查实际的压缩有效载荷大小(以字节为单位)。发送测试有效载荷后,检查运行 ngrok 的终端,你将看到类似以下内容:

压缩 - 自动方法

如你所见,服务器会自动解压缩 有效载荷,你可以直接在 req.body 中访问数据。就这样。

2.7 手动解压缩(可选)

在 Express 中间件中将 inflate 选项设置为 true 会自动解压缩 有效载荷。但是,如果你因任何原因要手动解压缩 有效载荷,则可以使用 zlib 模块来执行此操作。这是一个如何执行此操作的示例。只需将此路由添加到你现有的 app.js 文件中。

此代码段将 /webhook/manual 路由添加到你的服务器。与自动解压缩路由不同,此路由处理原始请求主体。它将传入的压缩数据收集到缓冲区中,检查 content-encoding ,如果它是 gzip,则使用 Node.js 的内置 zlib.gunzip 方法解压缩 有效载荷

此方法还会计算并记录压缩率,向你显示压缩数据和解压缩数据之间的确切大小差异。

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 头,然后删除它
  // 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");
  });
});

之后,你可以通过将压缩的 有效载荷 发送到 /webhook/manual 来测试手动解压缩路由。日志输出将显示压缩大小、解压缩大小和压缩率,如下所示。

压缩 - 手动方法

测试压缩后,你现在可以单击 Quicknode 仪表板 中的“创建 Stream”按钮来最终确定并激活你的 Stream 以接收压缩的实时数据。

结论

你已成功学习如何为 Quicknode Streams 启用压缩以及如何在 Express.js 应用程序中处理压缩的数据。该实现非常简单,只需几行代码即可处理解压缩,而节省是立竿见影且巨大的。

如果你有任何疑问,请直接 联系我们。如果你有任何想法或建议,例如你希望我们支持的新的目标地、功能、指标或数据集。

此外,请关注我们的 Twitter,加入我们的 DiscordTelegram 公告频道,以了解最新动态。

更多资源

我们 ❤️ 反馈!

如果你有任何反馈或对新主题的要求,请 告诉我们。我们很乐意听取你的意见。

  • 原文链接: quicknode.com/guides/qui...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
QuickNode
QuickNode
江湖只有他的大名,没有他的介绍。