当前位置: 首页 > 其它资源 > 正文
NGINX 与 Apache:最流行的开源 Web 服务器的比较

NGINX 与 Apache:最流行的开源 Web 服务器的比较

作者:大眼仔~旭 日期:3年前 (2021-09-03) 评论:0 条

摘要:Apache HTTP 服务器的第一个版本出现在 1995 年。 20 多年后的今天,该软件继续作为 Web 服务器之王统治 - 但并非没有竞争。 特别是俄罗斯网络服务器 NGINX(发音为“Engine-X”),也是一个开源项目,正在以惊人的速度获得市场份额。 对 Apache 基金会最有害的是什么:今天在 Alex…

Apache HTTP 服务器的第一个版本出现在 1995 年。 20 多年后的今天,该软件继续作为 Web 服务器之王统治 – 但并非没有竞争。 特别是俄罗斯网络服务器 NGINX(发音为“Engine-X”),也是一个开源项目,正在以惊人的速度获得市场份额。 对 Apache 基金会最有害的是什么:今天在 Alexa 排名中表现出色的大多数网站都已经通过 NGINX 交付了。 您可以查看 W3Techs 定期更新的 Web 服务器使用统计数据。

Nginx vs Apache

Nginx vs Apache

不仅仅是俄罗斯互联网巨头,例如搜索引擎 Ramblex 和 Yandex、电子邮件服务 Mail.RU 或社交网络 VK,都依赖于轻量级 Web 服务器; Dropbox、Netflix、WordPress 和 FastMail.com 等国际提供商也使用 NGINX 来提高其服务的性能。 Apache HTTP 服务器会很快过时吗?

注意

Apache HTTP 服务器是在 Apache 基金会赞助下运行的软件项目。 在互联网社区的经济术语中,Web 服务器的名称通常缩写为“Apache”。 我们还将遵循这一约定:在以下指南中,“Apache”将用于表示软件,而不是制造商。

Web 2.0 的挑战

Nginx, Inc. 产品主管 Owen Garrett 在 2015 年 10 月 9 日的一篇博客文章中将 Apache Web 服务器描述为 Web 1.0 的“支柱”,并强调了它对千禧年互联网发展的重要性. Web 服务器的巨大成功主要归功于软件的简单架构。然而,这是基于与万维网相对应的设计决策,无法与当今的决策进行比较。二十年前,网站建设要简单得多,带宽有限且昂贵,CPU 计算时间相对便宜。

今天我们正在处理第二代万维网,它从一个完全不同的角度展示:全球用户数量和网络流量成倍增加。互联网上网站的平均大小以及 Web 浏览器需要查询和呈现才能呈现它们的组件数量也是如此。越来越多的互联网社区从小就伴随着 Web 2.0 的可能性而成长。该用户组不熟悉等待几秒钟甚至几分钟才能下载网站。

近年来,这些发展一再给 Apache HTTP 服务器带来挑战。 Owen Garrett 将此归咎于 Apache 的基于进程的架构,因为鉴于快速增长的流量,它无法很好地扩展。这种困难是 2002 年开发 NGINX 的主要动机之一,它采用了完全不同的方法及其事件驱动架构。 NGINX 追溯到俄罗斯软件开发商 Igor Sysoev,他设计了该软件,该软件用作 Web 服务器、反向代理和电子邮件代理,特别是针对俄罗斯搜索引擎 Rambler 的需求。

我们并排比较这两个 Web 服务器,并查看它们的架构差异、配置和扩展选项,以及兼容性、文档和支持。

架构差异

Web 服务器 Apache 和 NGINX 基于根本不同的软件架构。 在连接管理、配置、客户端请求的解释以及静态和动态 Web 内容的处理方面发现了不同的概念。

连接管理

开源 Web 服务器 Apache 和 NGINX 在处理传入客户端请求的方式上存在本质差异。虽然 Apache 在基于进程的架构上运行,但 NGINX 的连接管理遵循事件驱动的处理算法。这使得以资源有效的方式处理请求成为可能,即使它们是同时从大量连接接收的。这被 NGINX 开发人员引用为比 Apache HTTP 服务器的一大优势。从 2.4 版本开始,它还提供了实现事件的可能性。因此,差异在于细节。

Apache Web 服务器遵循一种方法,其中每个客户端请求都由单独的进程或线程处理。使用单线程 – Apache HTTP 服务器的原始操作模式 – 这迟早会与 I/O 阻塞问题相关联:需要读取或写入操作的进程严格连续执行。后续请求将保留在队列中,直到前一个请求得到答复。这可以通过同时启动多个单线程进程来避免 – 这是一种与高资源消耗相关的策略。

或者,使用多线程机制。与单线程不同,其中每个进程只有一个线程可用于响应客户端请求,多线程提供了在同一进程中运行多个线程的可能性。由于 Linux 线程比进程需要更少的资源,因此多线程提供了补偿 Apache HTTP 服务器进程驱动架构的大量资源需求的能力。

可以使用以下三个多处理模块 (MPM) 之一来集成客户端请求与 Apache 的并行处理机制:mpm_prefork、mpm_worker、mpm_event。

mpm_prefork:Apache 模块“prefork”在单线程机制的基础上提供多进程管理。 该模块创建一个具有可用子进程供应的父进程。 每个子进程中运行一个线程,允许您一次回答一个客户端请求。 只要存在的单线程进程多于传入的客户端请求,就会同时处理这些请求。 可用的单线程进程的数量是使用服务器配置选项“MinSpareServers”和“MaxSpareServers”定义的。 Prefork 包含上面提到的单线程的性能缺陷。 但是,一个好处是独立进程的广泛独立性:如果连接因故障进程而丢失,通常不会影响其他进程中正在处理的连接。

mpm_worker:通过“worker”模块,Apache 用户可以使用多线程机制来并行处理客户端请求。每个进程可以启动多少线程是使用服务器配置选项“ThreadsPerChild”定义的。该模块为每个 TCP 连接提供一个线程。只要可用线程多于传入的客户端请求,就会并行处理这些请求。父进程 (httpd) 监视空闲线程。

用户可以使用“MinSpareThreads”和“MaxSpareThreads”命令来定义在多少空闲线程时将创建新线程或从内存中删除正在运行的线程。 worker 模块的资源需求比 prefork 模块低得多。但是由于连接不是在单独的进程中处理的,一个错误的线程可能会影响在同一个多线程进程中处理的所有连接。与 prefork 一样,worker 也容易受到由所谓的保持活动连接引起的过载(见下文)。

mpm_event:通过事件,Apache HTTP 服务器自 2.4 版以来拥有第三个多处理模块可用于生产用途。这提供了一个工作模块的变体,它在启动的线程之间分配工作负载。侦听器线程用于每个多线程进程,该进程接收传入的客户端请求并将相关任务分配给工作线程。

开发事件模块是为了优化与保持活动连接的联系,即保持 TCP 连接以允许传输进一步的客户端请求或服务器响应。如果使用经典的工作模块,工作线程通常会维护已经建立一次的连接,因此会被阻塞 – 即使没有收到进一步的请求。这可能导致具有大量保持活动连接的服务器过载。另一方面,事件模块将保持活动连接的维护外包给独立的侦听器线程。然后,工作线程不再被阻塞并可用于处理进一步的请求。

根据使用的模块,Apache 通过添加额外的进程或线程来解决并发问题(多个客户端请求的同时响应)。这两种解决方案策略都涉及额外的资源费用。这成为 Apache 服务器扩展的限制因素。

每个连接一个进程的方法的巨大资源需求源于必须为每个附加进程提供单独的运行时环境这一事实。这需要分配 CPU 时间和单独的存储。工作进程可用的每个 Apache 模块也必须为每个进程单独加载。另一方面,线程共享执行环境(程序)和内存中的地址空间。因此,附加线程的开销远低于进程的开销。但是,当使用上下文切换时,多线程也是计算密集型的。

上下文切换是指在系统中从一个进程或线程切换到另一个进程或线程的过程。为此,必须保存终止进程或线程的上下文,并且必须创建或恢复新进程或线程的上下文。这是一个耗时的管理过程,需要加载和保存 CPU 寄存器以及各种表和列表。

mpm_event 模块具有可用于 Apache HTTP 服务器的事件机制,它将传入连接的处理传输到侦听器线程。这使得终止不再需要的连接(包括保持活动连接)成为可能,从而减少资源消耗。但是,这并不能解决当侦听器线程通过其保持的连接将请求传递给单独的工作线程时发生的计算密集型上下文更改的问题。

相比之下,NGINX 的基于事件的架构实现了并发,而无需为每个新连接增加额外的进程或威胁。一个 NGINX 进程可以同时处理数千个 HTTP 连接。这是通过称为事件循环的循环机制实现的。这使得在威胁中异步处理客户端请求成为可能。

提示

理论上,NGINX 在处理连接时只使用一个单线程进程。 但是,为了优化利用硬件,Web 服务器通常从底层机器的每个处理器内核 (CPU) 一个工作进程启动。

与仅使用最小值和最大值限制活动进程或线程数的 Apache Web 服务器相反,NGINX 提供了一个可预测的进程模型,该模型针对底层硬件精确定制。 这包括一个主进程、缓存加载器和缓存管理器辅助进程,以及许多根据配置精确定义的处理器内核数量量身定制的工作进程。

主进程:主进程是执行所有基本操作的父进程。 其中包括导入服务器配置、端口绑定和创建以下所有进程类型。

辅助进程:NGINX 使用两个辅助进程进行缓存管理:缓存加载器和缓存管理器。

缓存加载器:缓存加载器负责将基于硬盘的缓存加载到内存中。

缓存管理器:缓存管理器的任务是确保硬盘缓存中的条目具有预先配置的大小,并在必要时修剪它们。 这个过程周期性地发生。

Worker 进程:Worker 进程负责处理连接、对硬盘的读写访问以及与上游服务器(向其他服务器提供服务的服务器)通信。 这意味着这些是 NGINX 进程模型中唯一持续活动的进程。

在配置期间由 NGINX 主进程启动的所有工作进程共享一组侦听器套接字。不是为每个传入连接启动一个新的线程进程,而是在每个工作进程中运行一个事件循环,它可以在不阻塞进程的情况下异步处理一个线程内的数千个连接。为此,侦听器套接字上的工作进程不断侦听传入连接触发的事件,接受它们,并在处理 HTTP 请求期间在套接字上执行读写进程。

NGINX 没有自己的机制可用于将连接分配到工作进程。相反,使用操作系统的核心功能。关于如何处理传入请求的方案由 HTTP、原始 TCP、SMTP、IMAP 和 POP3 的单独状态机提供。

一般来说,NGINX 可以被描述为一个事件处理程序,它从内核接收有关事件的信息,并告诉操作系统如何处理相关的任务。带有事件循环的任务异步处理基于偶数通知、回调和计时器。这些机制使工作进程可以将一个接一个的操作委托给操作系统,而不必等待操作的结果或客户端程序的响应。 NGINX 充当操作系统的编排器,并接管字节的读取和写入。

这种类型的连接管理只会为额外的连接创建最小的开销。所需要的只是一个额外的文件描述符 (FD) 和工作进程中最少的额外内存。另一方面,计算密集型上下文切换仅在事件循环内没有发生其他事件时才会发生。这种通过各种连接处理请求的效率使 NGINX 成为 WordPress.com 等频繁访问的网站的理想负载分配器。

概括

凭借其事件驱动的架构,NGINX 为 Apache HTTP 服务器的基于进程的连接管理提供了一种替代方案。 但这不足以解释为什么 NGINX 在基准测试中表现如此出色。 Apache 从 2.4 版开始,也支持客户端请求的基于事件的处理机制。 在比较 Web 服务器(例如 Apache 与 NGINX)时,请始终注意 Web 服务器在测试中使用的模块、它们的配置方式以及必须掌握的任务。

处理静态和动态 Web 内容

当涉及到动态 Web 内容时,NGINX 也遵循与 Apache HTTP 服务器不同的策略。

原则上:为了能够提供动态内容,Web 服务器需要能够访问能够处理所需编程语言(例如 PHP、Perl、Python 或 Ruby)的解释器。 Apache 有各种可用的模块,包括 mod_php、mod_perl、mod_python 或 mod_ruby,它们可以将相应的解释器直接加载到 Web 服务器中。因此,Apache 本身具备处理使用相应编程语言创建的动态 Web 内容的能力。用于准备静态内容的功能已经通过上述 MPM 模块实现。

另一方面,NGINX 仅提供用于交付静态 Web 内容的机制。动态内容的准备工作外包给专门的应用服务器。在这种情况下,NGINX 仅充当客户端程序和上游服务器之间的代理。通信通过 HTTP、FastCGI、SCGI、uWSGI 和 Memcached 等协议进行。 WebSphere、JBoss 或 Tomcat 提供了可能用于交付动态内容的应用程序服务器。 Apache HTTP 服务器也可用于此目的。

交付静态和动态内容的两种策略都有其优点和缺点。像 mod_php 这样的模块允许 Web 服务器自己执行 PHP 代码。不需要单独的应用程序服务器。这使得动态网站的管理变得非常简单。但是动态编程语言的解释器模块必须单独加载到负责交付内容的每个工作进程中。对于大量工作进程,这与大量开销相关。 NGINX 减少了这种开销,因为仅在需要时才调用外包解释器。

虽然 NGINX 被设置为与外包解释器交互,但 Apache 用户可以选择这两种策略中的任何一种。 Apache 也可以放置在用于解释动态 Web 内容的应用程序服务器之前。通常,为此使用协议 FastCGI。可以使用模块 mod_proxy_fcgi 加载相应的接口。

客户端请求的解释

为了能够令人满意地回答来自客户端程序(例如,Web 浏览器或电子邮件程序)的请求,服务器需要根据请求确定请求的是哪个资源以及在哪里找到它。

Apache HTTP 服务器被设计为 Web 服务器。 另一方面,NGINX 提供 Web 和代理服务器功能。 这种关注点的差异反映在软件解释客户端请求和在服务器上分配资源的方式上。

注意

Apache HTTP 服务器也可以在 mod_proxy 模块的帮助下设置为代理服务器。

Apache HTTP 服务器和 NGINX 都有允许传入请求被解释为文件系统中的物理资源或 URI(统一资源标识符)的机制。但是,虽然 Apache 默认基于文件工作,但基于 URI 的请求处理在 NGINX 中更为突出。

如果 Apache HTTP 服务器收到客户端请求,默认情况下它假定要从服务器的文件系统中检索特定资源。由于 Apache 使用 VirtualHosts 在同一服务器上以不同的主机名、IP 地址或端口号提供不同的 Web 内容,因此它必须首先确定请求所指的 VirtualHost。为此,Web 服务器将请求 URI 开头的主机名、IP 地址和端口号与主配置文件 httpd.conf 中定义的 VirtualHosts 进行匹配。

以下代码示例显示了一个 Apache 配置,其中两个域“www.example.com”和“www.other-example.com”在同一 IP 地址下运行:

1
2
3
4
5
6
7
8
9
10
11
12
NameVirtualHost *:80

<VirtualHost *:80>
ServerName www.example.com
ServerAlias example.com *.example.com
DocumentRoot /data/www/example
</VirtualHost>

<VirtualHost *:80>
ServerName www.other-example.com
DocumentRoot /data/www/other-example
</VirtualHost>

星号 (*) 用作 IP 地址的占位符。 Apache 通过将请求中包含的主机名与 ServerName 指令进行比较来决定将在哪个 DocumentRoot(Web 项目的起始目录)中搜索请求的资源。

如果 Apache 找到所需的服务器,则默认情况下将请求 URI 映射到服务器的文件系统。 Apache 为此使用包含在 URI 中的路径规范。 结合 DocumentRoot,这相当于资源路径。

对于请求 URI 为“www.example.org/public_html/images/logo.gif”的请求,Apache 将在以下文件路径下搜索所需资源(基于上面的示例):

1
/data/www/example/public_html/images/logo.gif

Apache 还将请求 URI 与配置中的可选文件和目录块进行匹配。 这使得可以为指向所选文件或目录(包括子目录)的请求定义特殊指令。

在以下示例中,为目录 public_html/images 和文件 private.html 定义了特殊指令:

1
2
3
4
5
6
7
8
9
10
11
12
13
<VirtualHost *:80>
    ServerName www.example.com
    ServerAlias example.com *.example.com
    DocumentRoot /data/www/example
      <Directory var/www/example.com/public_html/images>
          Order Allow,Deny
          Allow from all
     </Directory>
      <Files public.html>
          Order Allow,Deny
          Deny from all
      </Files>
</VirtualHost>

除了解释客户端请求的这个标准过程之外,Apache 还提供了 alias 指令,它允许您指定一个替代目录来搜索请求的资源而不是 DocumentRoot。 通过 mod_rewrite,Apache HTTP 服务器还提供了一个模块,允许用户重写或转发 URL。

如果您希望 Apache 检索存储在服务器文件系统之外的资源,请使用 location 指令。 这允许为特定 URI 定义指令。

代表 Apache 异常的是 NGINX 的标准情况。 首先,NGINX 解析请求 URI 并将其与 Web 服务器配置中的服务器和位置块进行匹配。 只有这样(如果需要)才会映射到文件系统并与根(与 Apache 服务器的 DocumentRoot 相当)进行组合。

使用服务器指令,NGINX 确定哪个主机负责响应客户端请求。 server 块对应于 Apache 配置中的 VirtualHost。 为此,请求 URI 的主机名、IP 地址和端口号与 Web 服务器配置中定义的所有服务器块相匹配。 以下代码示例显示了 NGINX 配置文件 nginx.conf 中的三个服务器块:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
server {
    listen 80;
    server_name example.org www.example.org;
    ...
}

server {
    listen 80;
    server_name example.net www.example.net;
    ...
}

server {
    listen 80;
    server_name example.com www.example.com;
    ...
}

在找到请求的服务器之前,请求 URI 不与服务器块中的位置块匹配。 为此,NGINX 读取指定的位置块并搜索与请求 URI 最匹配的位置。 每个位置块都包含特定的指令,告诉 NGINX 如何处理相应的请求。

可以将位置设置为解释为路径的前缀、精确匹配或正则表达式 (RegEx)。 在服务器配置的语法中,使用了以下修饰符:

无修饰符

该位置被解释为前缀。

URI 具有在 location 指令中定义的前缀的所有请求都被视为与位置匹配。

如果没有找到具体位置,则根据位置块中的信息处理请求。

 =

该位置被解释为完全匹配。

URI 与 location 指令中指定的字符串完全匹配的所有请求都将根据 location 块中的信息进行处理。

 ~

该位置被解释为正则表达式。

所有 URI 与正则表达式匹配的请求都会根据 location 块中的信息进行处理。

大小写字母被评估以进行匹配(区分大小写)。

 ~*

该位置被解释为正则表达式。

所有 URI 与正则表达式匹配的请求都会根据 location 块中的信息进行处理。

不为匹配评估大小写字母(不区分大小写)。

以下示例显示了三个位置块,它们显示了如何处理域“example.org”和“www.example.org”的信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
server {
    listen 80;
    server_name example.org www.example.org;
    root /data/www;

    location / {
        index index.html index.php;
    }

    location ~* \.(gif|jpg|png)$ {
        expires 30d;
    }
location ~ \.php$ {
        fastcgi_pass localhost:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

基于请求 URI 为“http://www.example.org:80/logo.gif”的客户端请求,NGINX 将按如下方式解释请求并交付所需的资源:

1
2
3
http://www.example.org:80/logo.gif

http://www.example.org:80/index.php

首先,NGINX 确定具体的前缀位置。为此,Web 服务器按顺序读取带有修饰符的所有位置,并在与请求匹配的第一个位置处停止。然后读出所有标有 RegEx 修饰符 (~) 的位置。此处也使用了第一个匹配项。如果找不到匹配的 RegEx 位置,则 Web 服务器使用先前确定的前缀位置作为后备。

例如,请求 URI ‘http://www.example.org:80/logo.gif’ 与前缀 location / 以及正则表达式 \.(gif|jpg|png)$ 匹配。因此,NGINX 会将请求与根一起映射到文件路径 /data/www/logo.gif 并将相应的资源交付给客户端。 expired 标头指示一个答案何时被视为过时 – 在当前示例中,它是在 30 天之后:expires 30d。

对URI为’http://www.example.org:80/index.php’的PHP页面的请求也匹配前缀位置/和RegEx位置~\.php$,得到优先处理。 NGINX 将请求转发到 FastCGI 服务器,该服务器侦听 localhost:9000 并负责处理动态 Web 内容。 fastcgi_param 指令将 FastCGI 参数 SCRIPT_FILENAME 设置为 /data/www/index.php。然后该文件在上游服务器上运行。变量 $document_root 对应于 root 指令,变量 $fastcgi_script_name 对应于主机名和端口号之后的 URI 部分:/index.php。

解释客户端请求的这个看似复杂的过程是由于使用 NGINX 的不同应用领域造成的。与 Apache HTTP 服务器的主要基于文件的方法相反,基于 URI 的请求解释在处理不同请求模式时实现了更大的灵活性。例如,当 NGINX 作为代理或邮件代理服务器而不是 Web 服务器运行时,这是必需的。

配置

据说 NGINX 在提供静态 Web 内容方面比 Apache HTTP 服务器具有巨大的速度优势。这部分是由于配置的差异。

除了主配置文件 httpd.conf 之外,Apache Web 服务器还为管理员提供了目录级管理选项。这使用 .htaccess 文件。原则上,这些分散的配置文件可以在您想要的任何服务器目录中实现。在 .htaccess 中定义的指令指示配置文件包含的目录及其子目录。在实践中,.htaccess 文件用于限制特定用户组的目录访问、设置密码保护或定义目录浏览、错误消息、转发或替代内容的规则。

请注意,这也可以在 httpd.conf 文件中集中配置。但是 .htaccess 在网络托管模型(例如共享托管)中变得相关,其中对主要配置文件的访问权限保留给托管服务提供商。通过 .htaccess 的分散配置允许用户允许对服务器文件系统的特定区域进行管理 – 例如,对于选定的项目目录 – 而无需访问主配置。更改也会立即生效,无需重新启动。

另一方面,NGINX 只提供中央配置的可能性。所有指令都在 nginx.conf 文件中定义。通过访问此文件,用户可以控制整个服务器。与 apache 不同的是,管理访问权限不限于选定的目录。这有优点也有缺点。 NGINX 的中央配置不如 Apache HTTP 服务器使用的概念灵活,但它提供了明显的安全优势:对 Web 服务器配置的更改只能由被授予 root 权限的用户进行。

然而,比安全论点更重要的是通过 .htaccess 使用分散配置的性能劣势。如果可以访问 httpd.conf,开发人员已经在 Apache HTTP 服务器文档中建议不要使用 .htaccess。其原因是 Apache 用于读取和解释配置文件的过程。

如前所述,Apache 在默认情况下遵循基于文件的方案来响应客户端请求。由于 Apache 体系结构允许分散配置,因此 Web 服务器在通往所请求资源的路径上沿文件路径搜索每个目录以查找 .htaccess 文件。它传递的所有配置文件都会被读取和解释 – 这个过程会显着降低 Web 服务器的速度。

注意

原则上,Apache 管理员可以自由选择是否使用 Web 服务器的分散配置选项并接受相关的优缺点。 在文档中,开发者强调所有 .htaccess 配置也可以在主配置 httpd.conf 中使用目录块进行。

想要禁用或限制 Apache 上的分散配置的用户可以使用主配置文件 httpd.conf 的目录块中的指令 AllowOverride 并将它们设置为 None。 这允许 Web 服务器忽略相应配置目录中的所有 .htaccess 文件。

示例配置向 Web 服务器指示应忽略主机 example.com 的所有 .htaccess 文件。

扩展可能性

我们比较中的两个 Web 服务器都在模块化系统上运行,其中核心系统可以根据需要使用其他组件进行扩展。 然而,在 1.9.10 版本之前,NGINX 在处理模块方面采用了与竞争产品完全不同的策略。

Apache HTTP 服务器有两个可用选项来扩展核心软件。 模块可以在开发期间编译成 Apache 二进制文件,也可以在运行时动态加载。

Apache 模块分为三类:

基本模块:Apache 基本模块包括提供 Web 服务器核心功能的所有组件。
扩展模块:这些扩展是 Apache Foundation 的模块,作为 Apache 发行版的一部分包含在内。 Apache 文档中提供了 Apache 2.4 标准安装中包含的所有模块的概述。
第三方模块:这些模块不是来自 Apache 基金会,而是由外部服务提供商或独立程序员提供。

另一方面,NGINX 长期以来将模块化限制为静态扩展组件,这些组件必须编译为软件核心的二进制文件。这种类型的软件扩展极大地限制了 Web 服务器的灵活性,特别是对于那些不习惯在没有相应发行版的包管理器的情况下管理自己的软件组件的用户。开发团队在这方面做了大量改进:从 1.9.11 版本(2016 年 2 月 9 日发布)开始,NGINX 支持将静态模块转换为动态模块的机制,以便它们可以在运行时通过配置文件加载。在这两种情况下,都使用服务器的模块 API。

请注意,并非所有 NGINX 模块都可以转换为动态模块。不应动态加载修补服务器软件源代码的模块。默认情况下,NGINX 还将可以同时加载的动态模块数量限制为 128。要增加此限制,请在 NGINX 源代码中将 NGX_MAX_DYNAMIC_MODULES 常量设置为所需的值。

除了 NGINX 文档的官方模块,用户还可以使用各种第三方模块。

兼容性和生态系统

Apache HTTP 服务器在万维网中占据主导地位已超过二十年,并且由于其市场份额,仍然被认为是准备 Web 内容的事实上的标准。 NGINX 也有一个 15 年的成功故事值得回顾。两种 Web 服务器都具有广泛的平台支持。虽然 Apache 被推荐用于所有类 Unix 操作系统以及 Windows,但 NGINX 文档引用了以下经过测试的系统:FreeBSD、Linux、Solaris、IBM AIX、HP-UX、macOS 和 Windows。

作为标准服务器,Apache 具有与第三方项目的广泛兼容性。所有相关的网络标准都可以使用模块进行集成。网络上的大多数玩家也熟悉 Apache 的概念。管理员和 Web 开发人员通常在负担得起的共享托管平台上实施他们的第一个项目。反过来,这些主要基于 Apache,以及通过 .htaccess 进行分散配置的可能性。 Apache HTTP 服务器也是用于开发和软件测试的各种开源程序包的一部分,例如 XAMPP 或 AMPPS。

NGINX 用户也可以使用一个庞大的模块生态系统。此外,开发团队还与各种开源和专有软件项目以及基础设施服务提供商(如 Amazon Web Services、Windows Azure 和 HP)建立了合作伙伴关系。

概括

两个 Web 服务器都已建立。 用户可以依赖一个庞大的生态系统。 与 NGINX 相比,Apache 的优势在于,多年来,庞大的用户社区已经将自己投入到 Web 服务器的基础知识中。 数以千计的管理员已经测试并改进了软件的源代码,这一事实不仅说明了 Web 服务器的安全性。 新用户还可以从大量经验丰富的 Apache 管理员中获益,他们可以通过论坛或邮件列表帮助社区解决问题。

总结

借助 Apache 和 NGINX,用户可以使用两个稳定、安全的开源项目。但是经过比较,这两个 Web 服务器都不是明显的赢家。这两个项目都基于根本不同的设计决策,这可能是优势也可能是劣势,这取决于软件的使用方式。

Apache HTTP 服务器提供了大量的模块库,连同灵活的配置选项,为软件打开了众多应用领域。 Web 服务器也可以是用于共享托管场景的标准软件,并将继续在其领域中与 NGINX 等轻量级 Web 服务器站在一起。使用模块将 PHP、Perl、Python 或 Ruby 等编程语言的解释器直接集成到 Web 服务器的能力允许在不使用单独的应用程序服务器的情况下交付动态 Web 内容。这使得 Apache HTTP 服务器成为在检索期间动态创建内容的中小型网站的舒适解决方案。

另一方面,NGINX 不提供任何本地处理动态 Web 内容或通过模块集成相应解释器的可能性。始终需要单独的应用程序服务器。对于中小型网站来说,这似乎是不必要的额外努力。然而,这样的架构显示了它在大型 Web 项目和不断增加的流量方面的优势。

一般情况下,NGINX 用作一组应用服务器前的负载均衡器。负载均衡器接受传入的请求,并根据请求的类型决定是否需要在后台将其转发到专门的服务器。静态网页内容由 NGINX 直接提供。如果客户端请求动态内容,则负载平衡器将请求提供给专用应用程序服务器。这会解释编程语言,将请求的内容组合成一个网页,并将其返回给负载均衡器,负载均衡器将其交付给客户端。通过这种方式,可以有效地管理高流量。

NGINX 缓存已经交付了一定时间的内容,因此新请求的动态内容可以由负载均衡器直接交付,而无需 NGINX 再次访问应用程序服务器。

将口译员外包给一台或多台独立的后端服务器的优势在于,如果需要添加额外的后端服务器,或者可以关闭不再需要的系统,可以轻松扩展服务器网络。在实践中,许多用户依靠 NGINX 和 Apache 的组合来进行这样的设置,并利用这两种服务器的优势。

声明:大眼仔旭 | 本文采用署名-非商业性使用-相同方式共享 4.0 国际许可协议[CC BY-NC-SA]进行授权
文章名称:《NGINX 与 Apache:最流行的开源 Web 服务器的比较
文章固定链接:http://www.dayanzai.me/nginx-vs-apache.html
本站资源仅供个人学习交流,请于下载后 24 小时内删除,不允许用于商业用途,否则法律问题自行承担。
转载声明
全部评论: (0条)
^_^ 暂无评论!

发表评论

返回顶部