插件概览

本页面简要介绍了插件与 Cloud Load Balancing 应用负载均衡器和媒体 CDN 的集成。

此功能在 Media CDN 中处于预览版阶段。

插件使用 WebAssembly (Wasm) 格式构建,并使用 Proxy-Wasm API。

  • Wasm 是一种开放且标准化的二进制指令格式,可让主机加载和运行包含客户提供的代码的 Wasm 模块。Wasm 在执行客户代码方面具有诸多优势,包括用于保障安全的沙盒、对多种语言的支持、可移植性、在业界得到广泛且不断增长的支持,以及相对于其他基于虚拟机 (VM) 的选项(例如 JavaScript)更高的性能。

  • Proxy-Wasm 是由 Google 发起的开源项目。它定义了一些 API,让您可以通过实现要在 HTTP 请求和响应处理期间执行的回调,来自定义网络代理的行为。

插件的工作原理

您可以将 Service Extensions 与应用负载均衡器和 Media CDN 搭配使用,如下所示:

  1. 按如下方式准备插件代码:

    1. 使用其中一个 Proxy-Wasm SDK 创建自定义代码:

    2. 将代码编译为 Wasm 模块。

    3. 将已编译的插件代码上传到 Artifact Registry 代码库。

  2. 创建包含上传的插件代码的插件。

  3. 在 Cloud Load Balancing 扩展程序或媒体 CDN 扩展程序中配置插件。

插件资源

Service Extensions 可帮助您创建以下关键资源,以便在处理路径中添加自定义代码:

  • 插件,其中包含您要部署的自定义代码。

  • 插件版本,即 Wasm 模块的版本。您可以指明插件要将哪个版本的 Wasm 模块用作其主(活跃)模块。

访问插件中的属性

Wasm 插件可以使用 proxy_get_property ABI 调用(属于 Proxy-Wasm ABI 的一部分)访问转发的属性。您可以检索的属性名称与特性名称相对应。

您可以将属性作为属性名称的路径表示法进行访问。例如,如需检索 request.host,您可以使用路径表示法,例如 {"request", "host"}。

以下概念性 Rust 示例演示了如何在 HttpContext 实现中访问转发的属性:

use proxy_wasm::traits::{HttpContext, RootContext};
use proxy_wasm::types::Action;

// ... inside your HttpContext implementation ...

fn on_request_headers(&mut self, _num_headers: usize, _end_of_stream: bool) -> Action {
    if let Some(host) = self.get_property(vec!["request", "host"]) {
        // host is a Vec, convert to string
        let host_str = String::from_utf8(host).unwrap_or_default();
        log::info!("Request host: {}", host_str);
    }

    if let Some(region) = self.get_property(vec!["source", "client_region"]) {
        let region_str = String::from_utf8(region).unwrap_or_default();
        log::info!("Client region: {}", region_str);
    }

    Action::Continue
}

限制

本部分列出了插件的一些限制。

资源限制

插件可使用的资源数量受到严格限制:

  • 插件每次调用最多可使用 1 毫秒的归一化 vCPU。CPU 毫秒取决于平台,但标准化平台大约相当于时钟速度为 4 GHz 的处理器。调用是独立计费的执行阶段,可以是请求标头、请求正文、响应标头或响应正文。

  • 每个虚拟机实例最多可使用 16 MiB 内存(Media CDN 插件为 4 MiB)。

    • 实例必须能够处理多达 1,000 个并发请求,这意味着插件可以为每个数据流保留最多 16 KiB 的内存(对于 Media CDN 插件,为 4 KiB)。总内存用量包括全局状态和堆栈分配。超出此限制的插件会被终止。

    • 我们建议您使用 C++ 和 Rust,因为它们生成的插件内存占用最小。不建议将 Go SDK 用于 Media CDN,因为 Go 运行时和垃圾回收器需要 2-3 MiB 的最低基准内存占用。

使用插件测试工具对插件的 CPU 和内存特性进行基准测试。

API 限制

  • 插件可以使用 Proxy-Wasm ABI 的一部分。插件不支持计时器、自定义指标、共享数据、共享队列或出站网络调用。

  • 不支持 HTTP 尾部事件。

标头操纵的限制

  • 任何变更(标头或正文块)的大小上限为 128 KiB。

  • 插件无法替换 ext_proc 流的处理模式。

  • 对于某些标头,不支持通过插件进行标头操作。处理器会忽略这些标头中的任何修改,并继续处理请求。

    对于 Media CDN 插件,不支持以下操作:

    • 标头:CDN-Loop、connection、keep-alive、proxy-authenticate、proxy-authorization、proxy-connection、te、trailers、transfer-encoding、upgrade 或 X-user-IP。
    • 以 x-forwarded、x-goog-、x-google、x-gfe 或 x-amz- 开头的标头。

    对于 Cloud Load Balancing 插件,不支持以下各项:

    • 标头:connection、keep-alive、proxy-authenticate、proxy-authorization、proxy-connection、sec-user-ip、te、trailer、transfer-encoding、upgrade、x-dont-count-ads、x-dont-show-ads、x-gr、x-proxyuser-ip 或 x-user-ip。

      此外,对于 LbTrafficExtension,以下标头也不受支持:method、authority、scheme 或主机标头。

    • 以 sec-gfe-、sec-google-、x-amz-、x-forwarded-、x-gfe-、x-goog-、x-google- 或 x-gproxy- 开头的标头。

HTTP/1.1 客户端和后端的限制

如果您为扩展程序配置 REQUEST_BODY 或 RESPONSE_BODY,则当负载均衡器收到匹配的请求时,它会从响应中移除 Content-Length 标头,并切换到分块正文编码。

后续步骤