首页 > 解决方案 > 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;
     ...
    }
}

标签: nginx

解决方案


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;
    }
}

推荐阅读