nginx 变量有多昂贵?

nginx 变量有多昂贵?

nginx 常见问题是否有一种适当的方法来使用 nginx 变量来缩短配置的各个部分,并将它们用作宏以使配置的各个部分作为模板工作?) 说(粗体是我的):

问:是否有一种正确的方法可以使用 nginx 变量来缩短配置的各个部分,并使用它们作为宏来使配置的各个部分作为模板工作?

答:变量不应该用作模板宏。变量在处理每个请求的运行时进行评估,因此与普通静态配置相比,它们的成本相当高昂。使用变量来存储静态字符串也是一个坏主意。相反,应该使用宏扩展和“include”指令来更轻松地生成配置,并且可以使用外部工具(例如 sed + make 或任何其他常见模板机制)来完成。

例如,add_header Content-Security-Policy为了更好的可读性,我使用的不是超长的代码:

set $CSP "default-src 'none'";

set $CSP "${CSP}; connect-src 'self'";

set $CSP "${CSP}; script-src 'self' https://*.domain.org 'unsafe-inline' 'unsafe-eval'";

set $CSP "${CSP}; style-src 'self' https://*.domain.org 'unsafe-inline'";

set $CSP "${CSP}; img-src 'self' data: https://*.domain.org";

set $CSP "${CSP}; font-src 'self' https://*.domain.org";

## CSP closing colon.
set $CSP "${CSP};";

add_header Content-Security-Policy "$CSP";

正确使用这个变量对 nginx 性能有多大影响? 有没有关于这个主题的性能测试/研究?

答案1

在处理每个请求期间,运行时会评估变量

想象一下,每个请求都必须从内存或运行时获取并保存变量,需要花费多少时间和内存?如果你有几个请求,这可能并不重要,但如果你有很多请求,那就非常严重了

这就像打开一个静态纯文本文件与一个动态文件。没有什么比直接访问纯文本文件更快的了。

在您的案例中,您使用了一个变量,然后多次设置它。由于缺乏基础设施,我无法使用 Nginx 本身进行基准测试,但我想分享适合您的案例的 PHP 脚本的基准测试。

您想要设置此文本:

默认 src'none';连接 src'self;脚本 src'self'https://.domain.org 'unsafe-inline' 'unsafe-eval'; style-src 'self' https://.domain.org 'unsafe-inline'; img-src 'self' 数据:https://.domain.org; font-src'self' https://.域名.org;

使用 PHP,您可以使用以下代码进行设置:

$csp = "default-src 'none'; connect-src 'self; script-src 'self' https://*.domain.org 'unsafe-inline' 'unsafe-eval'; style-src 'self' https://*.domain.org 'unsafe-inline'; img-src 'self' data: https://*.domain.org; font-src 'self' https://*.domain.org;";

但是由于某些原因,您可能希望在设置实际输出之前设置多次。因此代码将如下所示:

$csp =  "default-src 'none'";
$csp = $csp."; connect-src 'self'";
$csp = $csp."; script-src 'self' https://*.domain.org 'unsafe-inline' 'unsafe-eval'";
$csp = $csp."; style-src 'self' https://*.domain.org 'unsafe-inline'";
$csp = $csp."; img-src 'self' data: https://*.domain.org; font-src 'self' https://*.domain.org";
$csp = $csp.";";

我使用循环运行第一个代码 1000 万次,需要0.0725793838500982 秒第二个代码需要1.049282026290894 秒. 因此,第二个代码大约需要慢 15 倍。它仅显示请求时间基准,而不是内存、CPU、磁盘或任何其他资源使用情况基准。也许第二个代码也会比第一个代码占用更多的资源。

就像在 PHP 中发生的那样,它也会发生在 Nginx 运行时。正如 Nginx 文档中所说使用变量存储静态字符串成本高昂,而且也不是一个好主意。如果与上面的 PHP 类比相同,则成本为慢 15 倍

答案2

您应该对您的配置本身进行基准测试,因为您的特定设置中的许多因素都会影响速度减慢。

因此,首先设置所需 CSP 的配置。

使用例如 Siege 对配置进行基准测试:https://github.com/JoeDog/siege

然后,按照您的问题设置配置,并再次运行相同的基准测试。

这样您就可以获得有关您的设置的准确答案。

无论如何,我建议您使用 Ansible、Chef 或 Puppet 等配置管理系统来构建配置文件。在源代码中,您可以随意拆分行,但最终结果对于 nginx 来说是最佳的。

相关内容