如何基于请求XML Payload值配置Nginx实现动态proxy_pass跳转
前提说明
Nginx 原生不支持XML格式请求体的解析能力,要实现该需求需要给Nginx编译安装ngx_http_lua_module扩展模块,或直接使用内置该模块的OpenResty发行版,可大幅降低配置成本。
调整后的完整配置
# 先在http块定义上游服务,方便统一维护 upstream mail_server { server <你的mail服务域名/IP>; } upstream signin_server { server <你的signin服务域名/IP>; } server { # 保留原有server块的其他配置 set $proxy_target ""; # 提前声明变量避免Nginx启动报错 location /MailServices.aspx { lua_need_request_body on; # 强制Lua读取完整请求体 access_by_lua_block { local req_body = ngx.req.get_body_data() -- 正则匹配CommandType标签内容,自动过滤标签前后的空白字符 local cmd = ngx.re.match(req_body, [[<CommandType>%s*(.-)%s*</CommandType>]], "jo") if cmd and cmd[1] == "mail" then -- 若需要代理时携带路径后缀,可改为http://mail_server/mail ngx.var.proxy_target = "http://mail_server" elseif cmd and cmd[1] == "signin" then -- 若需要代理时携带路径后缀,可改为http://signin_server/signin ngx.var.proxy_target = "http://signin_server" else -- 未匹配到取值时的默认路由,可根据业务需要调整 ngx.var.proxy_target = "http://mail_server" end } proxy_pass $proxy_target; # 保留原有代理头配置 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Port $server_port; } }
注意事项
- 若请求体过大被Nginx缓存到临时文件,需要用
ngx.req.get_body_file()读取文件内容再解析,可根据业务请求体大小调整client_max_body_size和client_body_buffer_size配置,避免请求体落盘影响性能 - 正则匹配规则可根据实际请求中XML的格式调整,若存在命名空间、属性等特殊格式需要对应修改匹配规则
- 不想使用Lua扩展的场景,也可以用Nginx官方的njs(JavaScript)模块实现相同逻辑,实现思路一致仅语法不同
内容的提问来源于stack exchange,提问作者Kiruthika Senniappan
相关产品推荐
相关产品推荐

