映象請求

映象請求功能允許生成子請求來訪問額外的伺服器,實現多種業務場景。例如:

  • 向認證伺服器傳送請求,驗證透過後再進行服務訪問
  • 向 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,說明映象請求功能正常工作,成功獲取了映象伺服器的響應內容。