nginx - Nginx 转发基于来自另一个服务的响应
问题描述
我有一个用于反向代理到我的后端服务器的 nginx 设置。我有一个要求,如果从另一个 HTTP 请求成功检索到流量,则需要将流量发送到 IP,否则将其发送到另一个 IP。比如我有一个带有 request_param=abcd 的传入请求(它可以是任何值)。如果我能够从http://service/abcd检索 abcd ,则将其路由到 IP1,否则将其路由到 IP2。
如下所示:
server {
location /${abcd} {
if(http://service/$abcd returns HTTP 200)
then proxy_pass http://$http_host_1$request_uri;
else
proxy_pass http://$http_host_2$request_uri;
...
}
}
解决方案
Openresty 是解决这个问题的解决方案 - 它构建在 nginx 之上,让我们配置 lua 代码以拦截 nginx 请求处理并放置我们的自定义代码。 https://openresty-reference.readthedocs.io/en/latest/Directives/
我在访问阶段使用rewrite_by_lua根据条件重定向请求。 还需要使用库 lua-resty-http 来发出外部请求。
cd /usr/local/openresty/lualib/resty
curl -O https://raw.githubusercontent.com/ledgetech/lua-resty-http/v0.15/lib/resty/http.lua
curl -O https://raw.githubusercontent.com/ledgetech/lua-resty-http/v0.15/lib/resty/http_headers.lua
server {
listen 443;
location /location {
lua_need_request_body on;
set $backendurl 'http_host_1/request_uri';
rewrite_by_lua_block {
local body = ngx.req.get_body_data()
local abcd = ""
if (body) then
abcd = string.match(body, "my_pattern")
if (abcd ~= nil and abcd ~= '') then
local http = require "resty.http"
local httpc = http.new()
local external_url = "http://service/" .. abcd
local res, err = httpc:request_uri(external_url, {
method = "GET",
headers = {
["Content-Type"] = "application/json"
}
})
local response_status = res.status
if response_status == 404 then
ngx.var.backendurl = "http_host_2"
end
end
end
}
proxy_pass http://$backendurl/$uri;
}
}
推荐阅读
- forms - 使用电子表格中最后记录的响应中的数据预填充谷歌表单字段
- java - 如何使用 Wildfly 上的远程 EJB 将有关调用者/客户端的一些信息发送到服务器端?
- wordpress - Wordpress - WP Query:meta_query 关系被忽略
- haskell - `pure x :: IO a` 是纯值还是具有副作用的值?
- ios - 输入值后隐藏键盘?
- python - python安装中的文件模块失败
- python - 在不破坏现有回调的情况下将额外的可选参数传递给回调
- javascript - 为新的一年计算一个新的日期,同时保持一周中的适当日期(即:星期一)
- protractor - Protractor .npm-global 错误:指定了多个配置文件
- vb.net - 将 Curl 的 --key 和 --cert 翻译成 VB.NET