Envoy 结合 WebAssembly:打造高性能、可扩展的边缘计算解决方案
啥是 Envoy?
啥是 WebAssembly?
Envoy + WebAssembly = ?
Envoy + WebAssembly 的优势
边缘计算场景下的应用
1. 边缘网关
2. 边缘函数计算
3. 边缘 AI 推理
实战案例
总结
“ ভাই, 听说 Envoy 现在能跑 WebAssembly 了?这玩意儿到底能干啥?”
作为一名混迹云计算和边缘计算领域多年的老码农,我经常被问到类似的问题。今天,咱们就来好好聊聊 Envoy 和 WebAssembly 这对“黄金搭档”,看看它们如何在边缘计算领域擦出火花。
啥是 Envoy?
在深入探讨之前,咱们先来简单回顾一下 Envoy。如果你已经对 Envoy 了如指掌,可以直接跳到下一节。
Envoy 是 Lyft 开源的一款高性能、轻量级的服务网格代理。它最初是为了解决微服务架构中的网络通信问题而设计的。你可以把它想象成一个“超级路由器”,它可以拦截、处理和转发服务之间的网络流量。
Envoy 的核心优势在于:
- 高性能: Envoy 采用 C++ 编写,具有极高的性能和吞吐量。
- 可扩展性: Envoy 提供了丰富的插件机制,可以方便地扩展其功能。
- 可观察性: Envoy 提供了强大的监控和跟踪功能,可以帮助你深入了解服务的运行状况。
- 动态配置: Envoy 支持动态配置,可以实时更新配置而无需重启服务。
Envoy 已经成为服务网格领域的事实标准,被广泛应用于各种场景,包括微服务、API 网关、边缘代理等。
啥是 WebAssembly?
WebAssembly(简称 Wasm)是一种新型的二进制代码格式,它可以在现代 Web 浏览器中运行。Wasm 的设计目标是:
- 高性能: Wasm 代码可以接近原生代码的执行速度。
- 安全性: Wasm 代码运行在一个沙箱环境中,无法直接访问底层系统资源。
- 可移植性: Wasm 代码可以在不同的平台和操作系统上运行。
- 紧凑性: Wasm 代码体积小,加载速度快。
最初,Wasm 主要用于提升 Web 应用的性能。但随着技术的发展,Wasm 的应用场景已经远远超出了 Web 浏览器。现在,Wasm 已经成为一种通用的、可移植的、安全的运行时环境,被广泛应用于服务器端、边缘计算、嵌入式设备等领域。
Envoy + WebAssembly = ?
那么,当 Envoy 遇到 WebAssembly,会产生什么样的化学反应呢?
简单来说,Envoy 可以通过集成 Wasm 运行时来扩展其功能。这意味着你可以使用各种语言(如 C/C++、Rust、Go 等)编写 Wasm 模块,然后在 Envoy 中加载和运行这些模块。这些 Wasm 模块可以访问 Envoy 的 API,从而实现各种自定义的功能,例如:
- 自定义协议解析: 你可以编写 Wasm 模块来解析自定义的二进制协议,或者对现有的协议进行扩展。
- 流量控制: 你可以编写 Wasm 模块来实现更复杂的流量控制策略,例如限流、熔断、重试等。
- 安全增强: 你可以编写 Wasm 模块来实现自定义的认证、授权和加密机制。
- 数据转换: 你可以编写 Wasm 模块来对请求和响应数据进行转换,例如格式化、压缩、解压缩等。
- 边缘计算逻辑: 你可以在 Envoy 中运行 Wasm 模块,将计算逻辑部署到边缘节点,从而减少延迟、降低带宽消耗。
Envoy + WebAssembly 的优势
相比传统的 Envoy 插件开发方式(通常使用 C++),使用 WebAssembly 开发 Envoy 插件具有以下优势:
- 更低的开发门槛: 你可以使用你熟悉的语言(如 Rust、Go 等)来编写 Wasm 模块,而无需深入了解 Envoy 的 C++ 代码。
- 更快的开发速度: Wasm 模块的编译和部署速度通常比 C++ 插件更快。
- 更高的安全性: Wasm 模块运行在沙箱环境中,即使出现漏洞,也不会影响 Envoy 的稳定性。
- 更好的可移植性: Wasm 模块可以在不同的 Envoy 版本和平台上运行,无需重新编译。
- 更广泛的生态系统: Wasm 社区非常活跃,你可以找到大量的 Wasm 工具和库来帮助你开发 Envoy 插件。
边缘计算场景下的应用
在边缘计算场景下,Envoy + WebAssembly 的组合具有更大的潜力。以下是一些典型的应用场景:
1. 边缘网关
Envoy 可以作为边缘网关,部署在靠近用户或设备的边缘节点上。通过集成 Wasm 模块,Envoy 可以在边缘节点上实现以下功能:
- 协议转换: 将来自不同设备或协议的请求转换为统一的格式,方便后端服务处理。
- 数据过滤: 过滤掉无效或冗余的数据,减少传输到云端的数据量。
- 边缘缓存: 缓存静态资源或动态数据,减少对后端服务的请求。
- 安全防护: 在边缘节点上进行安全检查,防止恶意请求到达后端服务。
- 本地计算: 在边缘节点上执行一些简单的计算任务,例如数据聚合、格式转换等。
2. 边缘函数计算
Envoy 可以与 Wasm 运行时集成,构建边缘函数计算平台。用户可以将函数代码编译成 Wasm 模块,然后部署到 Envoy 中。Envoy 负责接收请求、调度函数执行、返回结果。这种方式可以实现:
- 低延迟: 函数在边缘节点上执行,无需将请求发送到云端,从而大大降低了延迟。
- 高可用性: 边缘节点通常具有较高的可用性,即使云端服务出现故障,边缘函数仍然可以正常运行。
- 节省带宽: 边缘函数可以在本地处理数据,减少了上传到云端的数据量。
- 数据隐私: 敏感数据可以在边缘节点上处理,无需上传到云端,从而保护了用户的数据隐私。
3. 边缘 AI 推理
Envoy 可以与 Wasm 运行时和 AI 推理引擎集成,构建边缘 AI 推理平台。用户可以将训练好的 AI 模型部署到 Envoy 中,然后在边缘节点上进行推理。这种方式可以实现:
- 低延迟: AI 推理在边缘节点上进行,无需将数据发送到云端,从而大大降低了延迟。
- 高吞吐量: Envoy 的高性能可以支持大量的 AI 推理请求。
- 节省带宽: 只有推理结果需要上传到云端,大大减少了带宽消耗。
- 数据隐私: 原始数据可以在边缘节点上处理,无需上传到云端,从而保护了用户的数据隐私。
实战案例
说了这么多,咱们来看一个实际的例子。假设我们需要在 Envoy 中实现一个简单的限流功能,限制每个 IP 地址每秒钟最多发送 10 个请求。我们可以使用 Rust 编写一个 Wasm 模块来实现这个功能。
以下是 Wasm 模块的 Rust 代码示例(简化版):
use std::collections::HashMap; use std::time::{SystemTime, UNIX_EPOCH}; use proxy_wasm::traits::*; use proxy_wasm::types::*; #[no_mangle] pub fn _start() { proxy_wasm::set_root_context(|_| -> Box<dyn RootContext> { Box::new(RateLimiter) }); } struct RateLimiter { counters: HashMap<String, (u64, u32)>, } impl Context for RateLimiter {} impl RootContext for RateLimiter { fn on_configure(&mut self, _: usize) -> bool { self.counters = HashMap::new(); true } fn on_http_request_headers(&mut self, _: usize, _: bool) -> Action { let now = SystemTime::now() .duration_since(UNIX_EPOCH) .unwrap(); let now_sec = now.as_secs(); let ip = self.get_property(vec!["source", "address"]).unwrap(); let ip_str = String::from_utf8(ip).unwrap(); let (last_sec, count) = self.counters.entry(ip_str.clone()).or_insert((now_sec, 0)); if *last_sec == now_sec { if *count >= 10 { self.send_http_response( 429, vec![("Retry-After", "1")], Some(b"Too Many Requests\n"), ); return Action::Pause; } *count += 1; } else { *last_sec = now_sec; *count = 1; } Action::Continue } }
这段代码使用 proxy-wasm
库来访问 Envoy 的 API。它维护了一个 HashMap
来记录每个 IP 地址的请求次数。在每个请求到达时,它会检查当前 IP 地址的请求次数是否超过了限制。如果超过了限制,就返回 429 状态码。否则,就更新计数器,并继续处理请求。
将这段代码编译成 Wasm 模块后,我们可以在 Envoy 的配置文件中加载这个模块:
static_resources: listeners: - address: socket_address: address: 0.0.0.0 port_value: 8080 filter_chains: - filters: - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager stat_prefix: ingress_http route_config: name: local_route virtual_hosts: - name: local_service domains: ["*"] routes: - match: prefix: "/" route: cluster: some_service http_filters: - name: envoy.filters.http.wasm typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm config: name: rate_limiter root_id: rate_limiter vm_config: vm_id: rate_limiter_vm runtime: envoy.wasm.runtime.v8 code: local: filename: /path/to/rate_limiter.wasm allow_precompiled: true - name: envoy.filters.http.router typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router clusters: - name: some_service connect_timeout: 0.25s type: STATIC lb_policy: ROUND_ROBIN load_assignment: cluster_name: some_service endpoints: - lb_endpoints: - endpoint: address: socket_address: address: 127.0.0.1 port_value: 9090
在这个配置文件中,我们添加了一个名为 envoy.filters.http.wasm
的 HTTP 过滤器。这个过滤器会加载并运行我们编写的 rate_limiter.wasm
模块。
总结
Envoy 和 WebAssembly 的结合为边缘计算带来了新的可能性。通过在 Envoy 中运行 Wasm 模块,我们可以构建出高性能、可扩展、安全可靠的边缘计算解决方案。如果你正在寻找一种构建边缘计算应用的方案,那么 Envoy + WebAssembly 绝对值得你考虑。
“老弟,这回明白了吧?Envoy + WebAssembly,强强联手,边缘计算,未来可期啊!”