在定時器中不能使用ngx.location.capture方法,否則會報錯API disabled in the context of ngx.timer,可以借用resty.http實現
1 直接使用方式
該方式使用httpc的接口實現如下
local http = require "resty.http"
-- 創建 HTTP 客戶端
local httpc = http.new()
-- 指定 Unix Domain Socket 地址 (格式: unix:/path/to/socket.sock)
local socket_path = "unix:/tmp/your_backend.sock"
-- 連接到 socket (端口必須設為 0)
local ok, err = httpc:connect(socket_path, 0)
if not ok then
ngx.log(ngx.ERR, "連接失敗: ", err)
return
end
-- 發送請求 (必須設置 Host 頭!)
local res, err = httpc:request({
method = "GET",
path = "/api/endpoint", -- 請求路徑
headers = {
["Host"] = "unix_domain_backend", -- 關鍵:任意有效 Host 值
["Connection"] = "close" -- 請求后關閉連接
}
})
-- 處理錯誤
if not res then
ngx.log(ngx.ERR, "請求失敗: ", err)
httpc:close()
return
end
-- 讀取響應體
local body = res:read_body()
-- 關閉連接
httpc:close()
-- 輸出結果
ngx.say("狀態碼: ", res.status)
ngx.say("響應體: ", body)
2 間接使用方式
該方式使用request_uri替代上面的connect,request和read_body,一步即可完成,但需要一個location轉發到nuix socket
local hc = httpc.new()
local url = "h.ttp://127.0.0.1/proxy_unix_domain/api/endpoint?unixaddr=your_backend.sock&arg=arg"
local res, err = hc:request_uri(url)
if not res then
ngx.log(ngx.ERR, "請求失敗: ", err)
else
-- 讀取響應體
local body = res.body
end
-- 關閉連接
httpc:close()
對應的location如下:
location ~ ^/proxy_unix_domain/(.*) {
proxy_set_header Host $host;
set $ori_uri $1;
rewrite_by_lua_block {
local uri = "/"..ngx.var.ori_uri
ngx.req.set_uri(uri)
}
proxy_pass h.ttp://unix:/tmp/$arg_unixaddr;
}
該location的代理地址通過參數來傳遞:unix:/tmp/your_backend.sock
請求uri通過改寫方式從原始請求截取