镜像请求
镜像请求功能允许生成子请求来访问额外的服务器,实现多种业务场景。例如:
- 向认证服务器发送请求,验证通过后再进行服务访问
- 向 WAF 服务器发送请求,安全检查通过后再允许访问
配置参数
- 类型:镜像请求的处理方式
- RAW:直接镜像原始请求
- CUSTOM:通过自定义 Lua 模块进行定制化处理
- 模块名称:当类型为 CUSTOM 时,指定处理请求的 Lua 模块名称(模块格式要求见下文示例)
- 上游:选择镜像请求的目标上游服务器
- 算法:负载均衡算法,支持 Hash、Chash、Roundrobin
- 重试次数:请求失败时的重试次数
- 发送超时:向镜像服务器发送数据的超时时间(单位:秒)
- 读取超时:从镜像服务器接收数据的超时时间(单位:秒)
- 连接超时:连接镜像服务器的超时时间(单位:秒)
- 异步:是否启用异步镜像请求(主请求无需等待子请求返回)(v25.12.1-1 新增)
- 转发请求体:是否转发原始请求的请求体 (v25.12.1-1 新增)
注意:当上游服务器启用健康检查时,镜像请求功能将默认启用快速失败机制。这意味着当健康检查显示没有可用的上游服务器时,系统将跳过镜像请求操作。
配置示例
1. 添加全局 Lua 模块
模块代码示例:
local _M = {}
function _M.before_mirror(ctx)
local content_length = tonumber(ngx.var.content_length)
if content_length and ctx.max_body_size > 4096 then
return ngx.DONE -- 跳过镜像操作
end
return ngx.OK
end
function _M.mirror_rewrite(ctx)
ngx.req.set_header('X-Real-IP', tostring(ngx.var.remote_addr))
end
function _M.mirror_header_filter(ctx)
ngx.log(ngx.ERR, "in mirror_header_filter")
end
function _M.mirror_body_filter(ctx)
ngx.log(ngx.ERR, "in mirror_body_filter")
end
function _M.after_mirror(ctx, resp)
ngx.header['mirror-response-body'] = resp.body
end
function _M.header_filter()
ngx.log(ngx.ERR, "in main request header filter")
end
function _M.body_filter()
ngx.log(ngx.ERR, "in main request body filter")
end
return _M
回调函数说明:
- before_mirror:子请求创建前调用,返回
ngx.DONE
可跳过镜像操作 - mirror_rewrite:子请求 rewrite 阶段调用,可修改子请求信息
- mirror_header_filter:子请求 header_filter 阶段调用,可修改子请求响应头
- mirror_body_filter:子请求 body_filter 阶段调用,可修改子请求响应体(异步模式下不会调用)
- after_mirror:子请求完成后调用(异步模式下不会调用)
- header_filter:主请求 header_filter 阶段调用
- body_filter:主请求 body_filter 阶段调用
2. 添加镜像服务器
3. 配置页面规则
4. 测试请求
$ curl http://test.com -v
* Rebuilt URL to: test.com/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to test.com (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: test.com
> User-Agent: curl/7.61.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Thu, 13 Oct 2022 08:25:22 GMT
< Content-Type: text/plain
< Transfer-Encoding: chunked
< Connection: keep-alive
< mirror-response-body: i am mirror server
< Server: openresty+
< Req-ID: 00000080000447f28b90004c
< Cache-Status: BYPASS
<
i am upstream
* Connection #0 to host test.com left intact
从响应结果可以看到,响应头中包含了 mirror-response-body: i am mirror server
,说明镜像请求功能正常工作,成功获取了镜像服务器的响应内容。