Nginx 多个 If 语句导致内存使用量猛增

Nginx 多个 If 语句导致内存使用量猛增

我们需要使用 nginx 通过 IP 地址阻止大量请求。这些请求由 CDN 代理,因此我们无法使用实际客户端 IP 地址进行阻止(它将是 CDN 的 IP 地址,而不是实际客户端的 IP 地址)。因此,我们有 $http_x_forwarded_for,其中包含我们需要针对给定请求阻止的 IP。

同样,我们也不能使用 IP 表,因为阻止代理客户端的 IP 地址不会产生任何效果。我们需要使用 nginx 根据 $http_x_forwarded_for 的值来阻止请求。

最初,我们尝试了多个简单的 if 语句: http://pastie.org/5110910

然而,这导致我们的 nginx 内存使用量大幅增加。我们的内存使用量从大约 40MB 增加到超过 200MB。

如果我们改变一些事情,并创建一个与必要 IP 地址匹配的大型正则表达式,则内存使用量相当正常: http://pastie.org/5110923

请记住,我们正在尝试阻止超过 3 或 4 个 IP 地址......更像是 50 到 100 个,这些地址可能包含在几个(20+)nginx 服务器配置块中。

有什么想法或建议吗?

我感兴趣的是为什么使用多个 if 块时内存使用量会大幅增加,以及是否有更好的方法来实现我们的目标。

答案1

我建议尝试地图模块像这样:

map $http_x_forwarded_for $deny_access {
    default     0;
    1.2.3.4     1;
    1.2.3.5     1;
    1.2.3.6     1;
}

if ($deny_access = 1) {
    return 403;
}

444 是特殊状态代码这会导致 nginx 断开连接而不发送响应。 在您的例子中,这是断开 nginx 和 CDN 之间的连接——然后 CDN 决定返回给客户端的内容。 我建议返回标准 403(禁止)。

答案2

另一个选择是使用真实IP模块将客户端 IP 设置为的值X-Forwarded-For,然后使用deny指令来控制访问。

但是,这将返回 403(而不是使用 444 返回的空响应)。它还要求 Ngnix 进行编译--with-http_realip_module— 如果您只能使用二进制分发,那么这可能不是一个选项。

相关内容