如何配置Envoy基于请求体限流?当前配置未生效
解决Envoy基于请求体MD5值限流的问题
问题原因
Envoy路由级限流的generic_key不支持直接解析{{ md5('%REQ_BODY%') }}这类模板表达式,会将其作为字面量发送给限流服务。要实现基于请求体MD5的限流,需要先通过前置处理将请求体MD5值存入请求头,再基于该请求头配置限流规则。
解决方案步骤
1. 添加请求体缓冲与Lua过滤器(计算MD5并写入自定义头)
修改http_filters配置,先缓冲请求体确保能读取完整内容,再通过Lua过滤器计算请求体MD5并写入自定义请求头X-Request-Body-MD5:
http_filters: # 缓冲请求体,调整max_request_bytes适配业务请求体大小 - name: envoy.filters.http.buffer typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.buffer.v3.Buffer max_request_bytes: 65536 # 示例为64KB,按需调整 # Lua过滤器计算请求体MD5并写入自定义头 - name: envoy.filters.http.lua typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua inline_code: | function envoy_on_request(request_handle) local body = request_handle:body() if body and body:length() > 0 then -- 读取完整请求体内容 local body_content = body:getBytes(0, body:length()) -- 计算MD5并转为十六进制字符串 local md5_obj = require("resty.md5"):new() md5_obj:update(body_content) local md5_raw = md5_obj:final() local md5_hex = require("resty.string").to_hex(md5_raw) -- 将MD5值写入自定义请求头 request_handle:headers():add("X-Request-Body-MD5", md5_hex) end end # 保留原有限流过滤器配置 - name: envoy.filters.http.ratelimit typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit domain: my_domain enable_x_ratelimit_headers: DRAFT_VERSION_03 rate_limit_service: transport_api_version: V3 grpc_service: envoy_grpc: cluster_name: rate-limit # 必须保留路由过滤器 - name: envoy.filters.http.router typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
2. 修改路由限流配置,读取自定义请求头
将原路由中的generic_key替换为request_header,读取生成的X-Request-Body-MD5头作为限流描述符值:
routes: - match: { prefix: "/api/v1/sms" } route: cluster: sms rate_limits: - actions: - request_header: header_name: "X-Request-Body-MD5" descriptor_key: body
3. 保持RateLimit服务配置不变
你的RateLimit服务原配置无需修改,descriptor.key: body会匹配Envoy发送的描述符,正常生效限流规则:
domain: my_domain descriptors: - key: body rate_limit: unit: minute requests_per_unit: 1
注意事项
- 确保Envoy镜像包含Lua过滤器组件(官方默认镜像已支持,自定义编译需开启
ENABLE_LUA选项)。 - 根据实际请求体大小调整
max_request_bytes,避免因请求体过大导致缓冲失败。 - 若请求体体积过大,该方案会增加内存占用与处理耗时,需结合业务场景评估性能影响。
内容的提问来源于stack exchange,提问作者Mohsen Saberi
相关产品推荐
相关产品推荐

