能否编写Envoy插件实现运行时请求目标解析?询动态路由最简方案
Envoy动态路由实现方案(针对高基数域名+动态映射场景)
核心方案:Lua过滤器实时解析域名并转发
针对你描述的场景——高基数通配符域名、已授权请求、动态内存映射表——最简的实现方式是利用Envoy的Lua HTTP过滤器,在请求处理阶段完成域名解析、映射查询和上游目标指定,无需编写C++插件,具体步骤如下:
1. 提取并解析请求目标域名
在Lua过滤器的on_request钩子中,从请求的:authority头(即Host头)提取xxxx前缀:
function envoy_on_request(req_handle) local authority = req_handle:headers():get(":authority") -- 匹配xxxx.foo.com格式,提取xxxx部分 local tenant_id = string.match(authority, "^([^.]+)%.foo%.com$") if not tenant_id then -- 非目标域名格式,直接放行或返回错误 return end
2. 查询动态内存数据库获取上游地址
通过Envoy的httpCall方法调用内存数据库的本地接口(比如Unix套接字或本地HTTP端口,确保低延迟),获取对应的内部IP:port:
-- 调用本地内存DB的查询接口 local db_resp = req_handle:httpCall( "local_memory_db", -- 预先配置的Cluster,指向内存DB的本地端点 { [":method"] = "GET", [":path"] = "/v1/mappings/" .. tenant_id, [":authority"] = "local-db" }, "", 300 -- 300ms超时,适配内存DB的高速响应 ) if not db_resp or db_resp:status() ~= 200 then -- 映射不存在或查询失败,返回404或降级处理 req_handle:respond( {[":status"] = "404"}, "Tenant mapping not found" ) return end
3. 动态指定上游转发目标
将查询到的IP:port设置为请求的上游目标,这里采用直接修改请求头的最简方式:
local upstream_target = db_resp:body() -- 修改请求的:authority头为上游IP:port,让router过滤器直接转发 req_handle:headers():set(":authority", upstream_target) -- 可选:标记请求来源,便于监控 req_handle:streamInfo():dynamicMetadata():set("tenant_routing", "tenant_id", tenant_id) end
配套Envoy配置要点
添加Lua过滤器到HTTP过滤器链:
在http_filters中插入Lua过滤器,指定上述脚本:http_filters: - name: envoy.filters.http.lua typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua inline_code: | -- 上述完整Lua代码 - name: envoy.filters.http.router typed_config: {}配置内存DB的本地Cluster:
定义一个static类型的Cluster,指向内存数据库的本地地址:clusters: - name: local_memory_db connect_timeout: 0.25s type: STATIC load_assignment: cluster_name: local_memory_db endpoints: - lb_endpoints: - endpoint: address: pipe: path: /var/run/memory_db.sock
方案优势
- 轻量高效:无需编写C++原生插件,Lua脚本开发成本低,本地调用内存DB几乎无性能损耗
- 实时性:每次请求都查询最新映射,完美适配频繁变更的映射关系
- 扩展性:支持高基数域名场景,无需预先配置大量路由规则或Cluster
- 兼容性:完全兼容Envoy的现有授权、监控等链路
内容的提问来源于stack exchange,提问作者Ghostrider
相关产品推荐
相关产品推荐

