Lua 基于请求方法是POST、PUT还是DELETE的nginx proxy_pass

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

我有两个实例在端口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 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;}