实战插件
昨天(Day 13)读透了 key-auth 这个"单机、看请求头就能拍板"的简单插件;今天升级到更复杂的实战插件:Redis 分布式限流(leader 选举 + Lua 脚本)、transformer(改 header/body)、request-block(拦截)。这些展示插件的进阶能力——外部依赖、分布式协调、跨阶段状态。
限流插件
extensions/cluster-key-rate-limit——基于 Redis 的分布式限流。核心问题:多个 Envoy 实例怎么共享一个限流计数?
Redis + Lua
// SDK redis_wrapper.go 的 RedisClient.Eval(...) 执行 Lua 脚本
// 固定窗口限流:一段 Lua 原子地"读当前计数 → 判断是否超限 → 未超则 +1"
// 走底层 proxy_redis_call(Higress fork 加的 ABI,Envoy 课 Day 17)
proxy_redis_call(Envoy 课 Day 17 讲的 Higress 定制 ABI)让 Wasm 插件能直接调 Redis。"原子操作解决并发竞态"是分布式限流的标准做法。❌ 不用 Lua(分三次命令):A 读到 99、B 也读到 99 → 两个都判"没超" → 都 +1 放行 → 实际放到 101,超了。
✅ 用 Lua(一段脚本原子跑):Redis 单线程,A 的脚本"读99→判未超→写100"整段跑完,B 的脚本才开始"读100→判到顶→拒绝(429)"。先到先得,绝不超发。
leader 选举
某些操作(定时清理、统计上报)只需一个 Envoy worker 干,用 DoLeaderElection(Day 12,SharedData + CAS + 60s 租约)选一个 leader。
transformer
extensions/transformer——改写请求/响应的 header 和 body(增删改)。展示插件怎么修改流经的数据。
AddHttpRequestHeader/RemoveHttpRequestHeader(改 header)和 body 缓冲能力(改 body)。改 body 要缓冲整个 body(BufferRequestBody)——所以要注册 ProcessRequestBody 回调,等 body 收齐再改。这是"数据改写类"插件的模板(AI 场景的 prompt 改写也是这套,Day 17)。request-block
extensions/request-block——最简单的拦截插件:按规则(URL/header/body 含某关键词)直接拒绝请求。
SendHttpResponseWithDetail(403)"——最小的"拦截"插件。适合作为"如何拦截请求"的入门样例(比 key-auth 更简单)。拦截类插件(黑名单、WAF)都是这个套路:匹配 → 拒绝。跨阶段状态
HttpContext 的 SetContext(key, val)/GetContext(key)(Day 12)在同一个请求的不同阶段间传值——因为 HttpContext 是每请求独立的,活在整个请求周期。比如请求头阶段存下"限流 key",响应体阶段取出来扣减。这是插件处理"需要看到请求全过程"的逻辑的关键机制。👶 小白:请求头阶段算好的东西,为什么不用一个全局变量存,非要塞进 HttpContext?
👨🏫 老师:因为网关同时在处理成千上万个请求。用全局变量,A 请求存的"限流 key"会被 B 请求覆盖——串味了。HttpContext 是每个请求独立一份(Day 12 的请求级 Context),A 存的 A 自己取、B 存的 B 自己取,互不干扰。这就像收费站给每辆车发一张"随车小票"记录信息,而不是所有车共用一块黑板。
单测 + 构建
插件有单测(main_test.go + proxytest 模拟 Envoy 环境),构建用官方 TinyGo builder 镜像(wasm-go-builder)编译成 .wasm,可推成 OCI 镜像(hgctl plugin build,Day 18)。
proxytest(proxy-wasm 的测试框架)模拟 Envoy 调回调,本地就能测。构建用 TinyGo(Go 的 Wasm 编译器)在容器里编译(保证环境一致)。GOOS=wasip1 GOARCH=wasm 是 Wasm 编译目标。Day 18 讲 hgctl plugin 一键构建/测试/发布。今日小结 + 动手
🧠 今天你应该能回答
- 分布式限流的难点?为什么要 Redis?
- 为什么限流用 Lua 脚本(原子性)?
- leader 选举解决什么?
- transformer 怎么改 body?为什么要缓冲?
- 跨阶段传值用什么?插件怎么测和构建?
✋ 动手
cd /Users/bitmart/work/codes/github/higress-group/higress/plugins/wasm-go/extensions
ls | head -40 # 看有多少插件
ls cluster-key-rate-limit/ transformer/ request-block/