nginx根据报文里字段转发至不同地址

nginx接收到post请求.请求报文里是一个json字符串,字符串里有个字段id。

根据id不同,转发到不同地址。

如果id=aaa,转发到www.aaa.com.test

如果id=bbb,转发到www.bbb.com.test

如何配置,请提供一个nginx.conf

要在 Nginx 中根据 POST 请求的 JSON 负载中的 id 字段的值进行转发,你可以使用 Nginx 的 ngx_http_lua_module 模块,这个模块允许你在 Nginx 配置中使用 Lua 脚本。下面是一个示例配置,它展示了如何根据 POST 请求的 JSON 负载中的 id 字段的值来转发请求。

首先,确保你的 Nginx 已经安装了 lua-nginx-modulelua-resty-http 库。这些可以通过 OpenResty 来安装,OpenResty 是一个集成了常用模块的 Nginx 发行版。

安装 OpenResty

你可以通过以下命令安装 OpenResty(假设你使用的是基于 Debian 的系统,如 Ubuntu):

bash 复制代码
sudo apt-get update
sudo apt-get install -y curl gnupg2 ca-certificates lsb-release ubuntu-keyring
curl -O https://openresty.org/package/pubkey.gpg
sudo apt-key add pubkey.gpg
sudo apt-get install -y apt-transport-https
echo "deb https://openresty.org/package/debian $(lsb_release -sc) openresty" | sudo tee /etc/apt/sources.list.d/openresty.list
sudo apt-get update
sudo apt-get install -y openresty

Nginx 配置 (nginx.conf)

下面是一个示例的 nginx.conf 配置,它使用 Lua 脚本来解析 POST 请求的 JSON 负载,并根据 id 字段的值转发请求。

nginx 复制代码
http {
    lua_package_path "/usr/local/openresty/luajit/share/lua/5.1/?.lua;;";
    lua_shared_dict my_cache 10m;

    server {
        listen 80;

        location / {
            content_by_lua_block {
                -- 读取 POST 请求体
                ngx.req.read_body()
                local data = ngx.req.get_body_data()

                if not data then
                    ngx.status = ngx.HTTP_BAD_REQUEST
                    ngx.say("No request body found")
                    return ngx.exit(ngx.HTTP_BAD_REQUEST)
                end

                -- 解析 JSON
                local cjson = require "cjson.safe"
                local json_data = cjson.decode(data)

                if not json_data or not json_data.id then
                    ngx.status = ngx.HTTP_BAD_REQUEST
                    ngx.say("Invalid JSON or missing 'id' field")
                    return ngx.exit(ngx.HTTP_BAD_REQUEST)
                end

                local id = json_data.id
                local target_url

                if id == "aaa" then
                    target_url = "http://www.aaa.com.test"
                elseif id == "bbb" then
                    target_url = "http://www.bbb.com.test"
                else
                    ngx.status = ngx.HTTP_NOT_FOUND
                    ngx.say("Unknown 'id' value")
                    return ngx.exit(ngx.HTTP_NOT_FOUND)
                end

                -- 创建 HTTP 客户端并转发请求
                local http = require "resty.http"
                local httpc = http.new()
                local res, err = httpc:request_uri(target_url, {
                    method = ngx.var.request_method,
                    body = data,
                    headers = ngx.req.get_headers(),
                    keepalive = false,
                })

                if not res then
                    ngx.status = ngx.HTTP_INTERNAL_SERVER_ERROR
                    ngx.say("Failed to forward request: ", err)
                    return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
                end

                -- 设置响应头
                for k, v in pairs(res.headers) do
                    ngx.header[k] = v
                end

                -- 发送响应体
                ngx.status = res.status
                ngx.print(res.body)

                -- 关闭 HTTP 客户端
                httpc:close()
            }
        }
    }
}

解释

  1. lua_package_pathlua_shared_dict:设置 Lua 模块的搜索路径和共享字典。
  2. serverlocation:定义一个服务器块和一个位置块来处理进入的请求。
  3. content_by_lua_block:使用 Lua 脚本处理请求。
  4. ngx.req.read_body():读取 POST 请求体。
  5. cjson.decode(data):解析 JSON 数据。
  6. 条件判断 :根据 id 字段的值决定目标 URL。
  7. resty.http :使用 resty.http 模块创建 HTTP 客户端并转发请求。
  8. 设置响应头和状态:将目标服务器的响应头和状态码传递给客户端。
  9. 发送响应体:将目标服务器的响应体发送给客户端。

确保你安装了 lua-cjsonlua-resty-http 库,这通常在使用 OpenResty 时已经包含在内。如果你手动安装 Nginx 和 Lua 模块,则需要确保这些库可用。

重启 Nginx

在修改完 nginx.conf 后,不要忘记重启 Nginx 以应用新的配置:

bash 复制代码
sudo systemctl restart nginx

这样,Nginx 将能够根据 POST 请求的 JSON 负载中的 id 字段的值来转发请求。

相关推荐
Guheyunyi1 小时前
消防管理系统如何重构现代空间防御体系
大数据·运维·人工智能·安全·信息可视化·重构
我是好小孩1 小时前
【Android】六大设计原则
android·java·运维·服务器·设计模式
孙同学要努力2 小时前
《Linux篇》进程状态——浅度、深度睡眠状态、僵尸状态、运行状态
linux·运维
jieyu11192 小时前
Linux Rootkit 详解
linux·运维·系统安全
宁檬精3 小时前
运维面试准备——综合篇(一)
linux·运维·服务器
weixin_456904273 小时前
工业自动化通信控制
运维·struts·自动化
帅帅梓4 小时前
nginx访问控制 用户认证 https
运维·nginx·https
b***25115 小时前
比斯特自动化|为什么焊接18650电池离不开点焊机?
运维·自动化
xgysimida5 小时前
一文搞懂supervisord是什么?
运维·运维开发
做运维的阿瑞6 小时前
从传统Linux部署到容器化:实践对比与工程化指南
linux·运维·服务器