Lua 基于请求方法是POST、PUT还是DELETE的nginx proxy_pass
我有两个实例在端口8080和9080上运行,其中9080实例是只读的 我不确定如何使用nginx,例如,如果请求方法是POST、PUT、DELETE然后发送到write实例(8080)或者发送到9080实例 我使用regex使用location做了一些事情,但这是不正确的 从中可以看出,可以调用“HTTP方法常量”,因此添加位置块是否正确:Lua 基于请求方法是POST、PUT还是DELETE的nginx proxy_pass,lua,nginx,Lua,Nginx,我有两个实例在端口8080和9080上运行,其中9080实例是只读的 我不确定如何使用nginx,例如,如果请求方法是POST、PUT、DELETE然后发送到write实例(8080)或者发送到9080实例 我使用regex使用location做了一些事情,但这是不正确的 从中可以看出,可以调用“HTTP方法常量”,因此添加位置块是否正确: location ~* "(ngx.HTTP_POST|ngx.HTTP_DELETE|ngx.HTTP_PUT)" { proxy_pass ht
location ~* "(ngx.HTTP_POST|ngx.HTTP_DELETE|ngx.HTTP_PUT)" {
proxy_pass http://127.0.0.1:8080;
谢谢我想你已经准备好了基础知识。也就是说,您已经在服务器上安装了Lua 5.1或更好的LuaJIT 2.0,使用ngx_Lua模块编译了Nginx,并根据需要配置了ngx_Lua 有了这一点,这将完成以下工作:
location /test {
content_by_lua '
local reqType = ngx.var.request_method
if reqType == ngx.HTTP_POST
OR reqType == ngx.HTTP_DELETE
OR reqType == ngx.HTTP_PUT
then
res = ngx.location.capture("/write_instance")
else
res = ngx.location.capture("/read_instance")
end
ngx.say(res.body)
';
}
location /write_instance {
internal;
proxy_pass http://127.0.0.1:8080;
}
location /read_instance {
internal;
proxy_pass http://127.0.0.1:9080;
}
更新
我想也许你在更大范围内特别使用了Lua。下面的示例也适用于与limit_相同的原则,除了
location /test {
if ($request_method !~* GET) {
# For Write Requests
proxy_pass http://127.0.0.1:8080;
}
# For Read Requests
proxy_pass http://127.0.0.1:9080;
}
“if”和“limit_except”块都有效地创建了一个嵌套的位置块,一旦条件匹配,则只会执行由此创建的内部位置块的内容处理程序(“proxy_pass”)
没有完全理解这就是为什么有时if被称为“邪恶”的原因,但在这种情况下,“如果”和“限制除外”共同的“邪恶”行为可能正是你想要的
所以有三个选择供你选择
但是请注意,如果您需要设置任何其他指令,则必须使用“if”或“limit_except”选项注意不要被“邪恶”行为所咬
也就是说,如果您在“if”或“limit_except”块内设置了一个指令,则该指令在其外部可能不会处于活动状态,类似地,外部设置的某些内容可能会在内部继承。因此,您必须观察这两种方法是如何继承默认值的,还是不继承默认值(视情况而定)
本页列出的所有潜在问题同样适用于此处的“如果”和“限制除外”。基于Lua的脚本编写方法将避免该页面上建议的许多潜在陷阱
祝你好运 我刚刚做了一个快速测试,这对我很有效:
服务器{
地点/{
#此代理\u通行证用于不符合以下条件的请求:
#与限制匹配,除非
代理通行证http://127.0.0.1:8080;
除PUT POST DELETE外的限制{
#对于*不是*PUT、POST或DELETE的请求,
#发送至:9080
代理通行证http://127.0.0.1:9080;
}
}
}
如果有人想通过请求方法简单地生成条件,语法如下:
if ($request_method = DELETE ) {
. . .
}
我推荐使用nginx映射函数。这超出了您的位置块:
map $request_method $destination {
default 8080;
PUT 9080;
POST 9080;
DELETE 9080;
}
proxy_pass http://127.0.0.1:$destination
然后在您的位置块中:
map $request_method $destination {
default 8080;
PUT 9080;
POST 9080;
DELETE 9080;
}
proxy_pass http://127.0.0.1:$destination
这也是所有正则表达式,因此您可以执行以下操作:
map $request_method $cookie_auth $destination {
default 8080;
"^POST " 9080;
"^PUT someAuthCookieValue" 9080;
}
此外,这完全避免了使用if。太棒了。我使用它将WordPress集群中的所有写入通信量定向到远程节点上的一个FastCGI TCP套接字,但将读取通信量发送到本地FastCGI UNIX套接字。您能更好地解释这个问题吗?你试过那种设置吗?您是否有任何错误(哪些错误)?它也不依赖任何第三方模块。这非常令人困惑,首先您说
不匹配限制,除了,在限制之前,除了您说不
,因此如果我有GET
请求,它不匹配限制,除了(因此,根据评论,8080
),但GET
也不是“PUT、POST或DELETE”,因此9080
我已将第二条注释移到limit_Exception块中。这是否让您更清楚哪些请求将由该内部块处理,而不是外部代理传递?感谢您的详细解释,因此我需要注意IfiSEvil是否需要运行其他指令。我可能需要,因为我还需要包括ude特定URL,如位置~*“(登录|新内容)”{…但我会设法解决这个问题,然后带着我的nginx.conf文件回到这里,看看是否可以改进。试着按具体问题将查询分开。我假设,有了这三个选项,关于如何基于请求方法在nginx中路由请求的具体问题已经得到了详尽的回答。您可以选择“如果”直接或“限制除外”这是一种IF语句,考虑到潜在的问题,或者使用脚本方法(如Lua示例)来避免这些问题。如果有其他问题,您可能需要考虑接受一个或另一个答案,并提出一个新问题。这是一个信息性的响应。我正在尝试使用您的第一个解决方案。(按lua方法编写的内容),但我注意到调用ngx.say(res.body)
不包括响应对象的标题,只包括主体。如何将响应的标题写入最终的ngx响应?。尽管,我必须提到,nginx团队不建议使用IF-in-config:我想知道为什么这一个得到的投票数如此之少,实际上是最好的答案。但是,我给出了第二个示例正确地说,regex用法是由~
字符串前缀定义的,正确的等价物是映射“$request\u method:$cookie\u auth”$destination{default 8080;“^POST:'9080;“^PUT:someAuthCookieValue$”9080;}