十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Envoy 压缩库全景:zlib-ng、Brotli 与 zstd 的集成方式及 Bazel 定制实践

Envoy 压缩库全景:zlib-ng、Brotli 与 zstd 的集成方式及 Bazel 定制实践 Envoy 压缩库全景zlib-ng、Brotli 与 zstd 的集成方式及 Bazel 定制实践【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy本文基于 Envoy 官方架构文档 Compression Libraries 展开讲清 Envoy 当前使用的三个底层压缩库zlib-ng、brotli、zstd各自的角色定位并结合仓库源码剖析 gzip 压缩器对 zlib API 的具体调用方式、Bazel 构建系统中压缩库的选择机制以及如何通过--envoy//bazel:zlib开关链接替代实现。读完本文你将能够理解 Envoy 压缩扩展的依赖边界、在构建层面切换 zlib 实现的完整步骤以及各压缩库在源码中的落点与消费方。一、Envoy 的压缩库选型zlib-ng、brotli、zstd官方文档明确说明当前 Envoy 使用zlib-ng、brotli和zstd三个库作为压缩底层实现。三者并非平权关系在仓库的依赖清单 bazel/deps.yaml 中可以看到它们各自的用途分类use_category与关联扩展压缩库用途分类deps.yaml关联扩展名备注brotlidataplane_core、dataplane_extenvoy.compression.brotli.compressor、envoy.compression.brotli.decompressorMIT 许可zstddataplane_extenvoy.compression.zstd.compressor、envoy.compression.zstd.decompressorzstandard 实现zlib-ngcontrolplane、dataplane_core作为 zlib 的替代品被广泛链接zlib fork (higher performance)从 bazel/deps.yaml 的依赖元数据可以确认几个事实zlib-ng 被归类为controlplanedataplane_core说明它不只是某个压缩扩展的可选依赖而是被 Envoy 核心代码数据面与控制面直接链接的基础库brotli 与 zstd 的用途分类为数据面扩展对应envoy.compression.*系列压缩器/解压缩器扩展属于可按需启用的模块化组件各库的实际版本由 MODULE.bazel 声明当前仓库锁定为zlib-ng 2.3.2.envoyL122、zstd 1.5.7.bcr.1L123、brotli 1.2.0.bcr.1L24其中zlib-ng采用了 envoy 定制的 BCR 版本。二、为什么选择 zlib-ng 而不是原版 zlib原始文档特别用了一个 note 说明了选择 zlib-ng 的动机zlib-ng 是一个 fork承载了多个第三方贡献的优化这些优化被认为对提升压缩性能有帮助Envoy 因此直接以 zlib-ng 作为 zlib 实现来构建。这一选择在源码层面体现为透明替换——Envoy 代码统一按标准 zlib 头文件编程替换只发生在链接期。以下两个消费方都能直接佐证source/extensions/common/aws/eventstream/eventstream_parser.cc 直接#include zlib.h使用 zlib 解压 APIsource/extensions/common/wasm/foreign.cc 调用uncompress()处理 Wasm 侧传入的压缩数据。也就是说只要构建系统把zlib这个符号解析到 zlib-ng所有标准 zlib 调用路径都会自动获得新实现的优化收益业务代码零改动。gzip 压缩器zlib API 的调用细节gzip 压缩扩展的压缩器实现位于 source/extensions/compression/gzip/compressor/zlib_compressor_impl.cc其ZlibCompressorImpl展示了 zlib 流式压缩的典型用法流初始化构造函数以默认 4096 字节chunk_size创建 zlib 流并将zalloc/zfree/opaque置为Z_NULL即使用库内部分配器init()调用deflateInit2()参数依次为压缩级别comp_level、Z_DEFLATED算法、window_bits、memory_level默认 8、压缩策略comp_strategy任一参数非法会触发RELEASE_ASSERT压缩级别枚举头文件 zlib_compressor_impl.h 中的CompressionLevel::Standard Z_DEFAULT_COMPRESSION将配置层概念直接映射到 zlib 常量流式处理compress()遍历Buffer::Instance的每个RawSlice逐个喂入deflate()并使用Z_NO_FLUSH——即尽可能压缩但不立即输出保证跨 slice 的压缩上下文连续流结束时根据状态选择Z_FINISH流结束或Z_SYNC_FLUSH反压与断言deflateNext()对Z_STREAM_END、Z_BUF_ERROR输入耗尽等返回码做严格断言任何非预期状态都会直接让进程失败而不是静默丢数据。对应的解压侧 source/extensions/compression/gzip/decompressor/zlib_decompressor_impl.cc 使用inflateInit2()带window_bits参数以支持 gzip/zlib 两种容器格式与压缩侧形成对称实现。整个压缩扩展族目录结构为source/extensions/compression/ ├── common/ # 压缩器/解压缩器公共接口与抽象基类 ├── gzip/ # gzipcompressor decompressor基于 zlib-ng ├── brotli/ # brotlicompressor decompressor ├── zstd/ # zstdcompressor decompressor其中 source/extensions/compression/common/compressor/BUILD 定义抽象接口三个具体实现的 BUILD 文件如 source/extensions/compression/gzip/compressor/BUILD分别链接各自的外部库依赖。上层由 source/extensions/filters/http/compressor HTTP 压缩过滤器和 source/extensions/filters/http/decompressor 解压缩过滤器统一调度这些底层实现。三、Bazel 构建系统压缩库如何被链接、如何替换3.1//bazel:zlib构建开关官方文档指出的关键定制入口是 Bazel 选项--envoy//bazel:zlibzlibEnvoy 默认用 zlib-ng 构建但可以通过该选项链接替代实现前提是要在 Bazel 中注册相应的 zlib 仓库。该选项在仓库中的定义见 bazel/BUILDlabel_flag( name zlib, build_setting_default zlib-ng, )这是一个label_flag默认值指向zlib-ng外部仓库而各使用 zlib 的cc_library通过deps引用//bazel:zlib这个开关标签。因此替换实现的标准流程为在 Bazel 仓库规则中注册你的 zlib 仓库例如zlib确保其提供与 zlib-ng 兼容的cc_library目标构建时传入--envoy//bazel:zlibzlib所有依赖//bazel:zlib的目标即切换到新仓库数据面与控制面的所有标准 zlib 调用上文 eventstream、wasm foreign、gzip 压缩器随之链接到新实现源码无需修改。3.2 打包为libz.a给 foreign_cc 依赖准备传统归档zlib-ng 通过 BCR 提供的是 Bazel 内部格式的cc_library归档而部分foreign_cc的configure_make规则例如 QAT 压缩相关的 qatzip期望能通过-lz找到传统的libz.a文件。为此bazel/external/BUILD 做了两级转换# 将 zlib-ng cc_library 收敛为静态库归档 cc_static_library( name zlib_static, target_compatible_with [platforms//os:linux], deps [//bazel:zlib], ) # 生成按 -lz 可定位的 lib/libz.a genrule( name zlib_archive, srcs [:zlib_static], outs [lib/libz.a], cmd mkdir -p $$(dirname $) cp $ $, target_compatible_with [platforms//os:linux], visibility [//visibility:public], )注意zlib_static的deps正是//bazel:zlib开关标签——这也意味着如果你替换了 zlib 实现libz.a归档会自动跟随新实现重新打包foreign_cc 依赖链路无需额外适配。说明原始文档引用的构建选项文件路径为bazel/external/zlib_ng.BUILD该文件在当前仓库中已不再存在zlib 相关的静态库打包规则已收敛到 bazel/external/BUILD评估 zlib-ng 构建选项时应以该文件为准。四、验证与深入路径确认压缩扩展注册envoy.compression.gzip.compressor、envoy.compression.brotli.compressor、envoy.compression.zstd.compressor等扩展名可在 bazel/deps.yaml 的extensions字段中交叉核对gzip 扩展名在 source/extensions/compression/gzip/compressor/BUILD 中登记。确认版本边界三个库的精确版本以 MODULE.bazel 与 MODULE.bazel 的bazel_dep声明为准本文所列 2.3.2.envoy / 1.5.7.bcr.1 / 1.2.0.bcr.1 即当前仓库快照的锁定值。切换 zlib 实现的最小动作注册新仓库 --envoy//bazel:zlib你的仓库其余链接与打包链路zlib_static→zlib_archive→-lz自动跟随开关标签生效。小结Envoy 的压缩栈由三个库构成分工zlib-ng 作为标准 zlib 的高性能替代品承担核心基础设施角色controlplanedataplane_core被 gzip 压缩/解压缩器及 eventstream、wasm 等多个模块直接链接brotli 与 zstd 则以模块化扩展envoy.compression.*形式提供数据面可选压缩能力。构建层面通过//bazel:zlib这个label_flag实现了压缩库实现的构建期可插拔替换实现只需一条 Bazel 开关加仓库注册且libz.a归档链路会自动适配。掌握这一机制后你可以按部署环境的性能或合规要求如特定平台优化的 zlib 变体定制 Envoy 的压缩底层而无需触碰任何 C 源码。【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表