ApachevsNginx:实际考虑

来自菜鸟教程
跳转至:导航、​搜索

介绍

Apache 和 Nginx 是世界上最常见的两种开源 Web 服务器。 他们共同负责为互联网上超过 50% of 的流量提供服务。 这两种解决方案都能够处理不同的工作负载并与其他软件一起提供完整的 Web 堆栈。

尽管 Apache 和 Nginx 有许多共同点,但它们不应该被认为是完全可以互换的。 每个都有自己的优点,本文将介绍每个的优点和缺点。

总体概述

在深入探讨 Apache 和 Nginx 之间的区别之前,让我们快速了解一下这两个项目的背景及其一般特征。

阿帕奇

Apache HTTP Server 由 Robert McCool 于 1995 年创建,自 1999 年以来一直在 Apache 软件基金会的指导下开发。 由于 HTTP Web 服务器是基金会的原始项目,并且是迄今为止他们最受欢迎的软件,它通常被简称为“Apache”。

至少从 1996 年到 2016 年,Apache Web 服务器是互联网上最受欢迎的服务器。 由于这种流行,Apache 受益于来自其他软件项目的大量文档和集成支持。

管理员经常选择 Apache 是因为它的灵活性、功能和近乎普遍的支持。 它可以通过可动态加载的模块系统进行扩展,并且可以直接服务于许多脚本语言,例如 PHP,而无需额外的软件。

Nginx

2002 年,Igor Sysoev 开始研究 Nginx,以解决 C10K 问题,这对 Web 服务器来说是一个能够处理一万个并发连接的突出挑战。 Nginx 于 2004 年公开发布,依靠异步、事件驱动的架构实现了这一目标。

Nginx 由于其轻量级的占用空间和在最少的硬件上轻松扩展的能力,其受欢迎程度已经超过了 Apache。 Nginx 擅长快速提供静态内容,拥有自己强大的模块系统,并且可以根据需要将动态请求代理到其他软件。

管理员经常选择 Nginx 是因为它的资源效率和负载下的响应能力,以及其简单的配置语法。

连接处理架构

Apache 和 Nginx 之间的一个区别是它们处理连接和网络流量的特定方式。 这可能是它们在负载下响应方式的最显着差异。

阿帕奇

Apache 提供了多种多处理模块(Apache 将这些 MPM 称为 MPM),这些模块决定了如何处理客户端请求。 这允许管理员配置其连接处理架构。 这些都是:

  • mpm_prefork:这个处理模块产生进程,每个进程都有一个线程来处理请求。 每个孩子一次只能处理一个连接。 只要请求数小于进程数,这个 MPM 就非常快。 但是,请求数超过进程数后,性能会迅速下降,因此在很多场景下,这并不是一个好的选择。 每个进程对 RAM 消耗都有显着影响,因此这种 MPM 难以有效扩展。 如果与其他未考虑线程构建的组件一起使用,这可能仍然是一个不错的选择。 例如,PHP 并不总是线程安全的,因此建议将此 MPM 作为使用 mod_php(用于处理这些文件的 Apache 模块)的安全方式。
  • mpm_worker:这个模块产生可以管理多个线程的进程。 这些线程中的每一个都可以处理单个连接。 线程比进程更高效,这意味着这个 MPM 比 prefork MPM 的可扩展性更好。 由于线程多于进程,这也意味着新连接可以立即占用空闲线程,而不必等待空闲进程。
  • mpm_event:此模块在大多数情况下类似于工作模块,但已针对保持连接进行了优化。 使用worker MPM时,只要连接保持活动状态,无论是否正在主动发出请求,连接都会保持线程。 事件 MPM 通过留出专用线程来处理保持活动连接并将活动请求传递给其他线程来处理保持活动连接。 这可以防止模块因保持活动请求而陷入困境,从而加快执行速度。

Apache 提供了一个灵活的架构来选择不同的连接和请求处理算法。 提供的选择主要是服务器发展的一个功能,以及随着互联网格局的变化对并发性的需求不断增加。

Nginx

Nginx 是在 Apache 之后出现的,对站点大规模面临的并发问题有了更多的认识。 因此,Nginx 从一开始就被设计为使用异步、非阻塞、事件驱动的连接处理算法。

Nginx 产生工作进程,每个工作进程都可以处理数千个连接。 工作进程通过实现持续检查和处理事件的快速循环机制来实现这一点。 将实际工作与连接分离允许每个工作人员仅在触发新事件时才关注连接。

工作人员处理的每个连接都放置在事件循环中。 在循环中,事件被异步处理,允许以非阻塞方式处理工作。 当连接关闭时,它会从循环中移除。

这种连接处理方式允许 Nginx 以有限的资源进行扩展。 由于服务器是单线程的,并且不会产生进程来处理每个新连接,因此内存和 CPU 使用率往往保持相对一致,即使在负载很重的时候也是如此。

静态与动态内容

就现实世界的用例而言,Apache 和 Nginx 之间最常见的比较之一是每个服务器处理静态和动态内容请求的方式。

阿帕奇

Apache 服务器可以使用其传统的基于文件的方法来处理静态内容。 这些操作的性能主要是上述 MPM 方法的函数。

Apache 还可以通过将相关语言的处理器嵌入到其每个工作实例中来处理动态内容。 这允许它在 Web 服务器本身内执行动态内容,而无需依赖外部组件。 这些动态处理器可以通过使用可动态加载的模块来启用。

Apache 内部处理动态内容的能力是 LAMP 流行的直接贡献者(Linux-Apache-MySQL-P[X157X ]HP) 架构,因为 PHP 代码可以由 Web 服务器本身本地执行。

Nginx

Nginx 没有任何原生处理动态内容的能力。 为了处理 PHP 和其他对动态内容的请求,Nginx 必须将请求交给外部库执行并等待输出返回。 然后可以将结果转发给客户端。

这些请求必须由 Nginx 和外部库使用 Nginx 知道如何说话的协议之一(http、FastCGI、SCGI、uWSGI、memcache)交换。 在实践中,PHP-FPM,一种 FastCGI 实现,通常是一种插入式解决方案,但 Nginx 在实践中并没有与任何特定语言紧密耦合。

但是,这种方法也有一些优点。 由于动态解释器没有嵌入在工作进程中,它的开销只会出现在动态内容中。 静态内容可以直接提供,只有在需要时才会联系翻译。

分布式与集中式配置

Apache 和 Nginx 在允许基于每个目录进行覆盖的方法上有很大不同。

阿帕奇

Apache 包含一个选项,通过检查和解释内容目录本身的隐藏文件中的指令,允许在每个目录的基础上进行附加配置。 这些文件称为 .htaccess 文件。

由于这些文件本身位于内容目录中,因此在处理请求时,Apache 会检查所请求文件路径的每个组件是否存在 .htaccess 文件并应用其中找到的指令。 这有效地允许 Web 服务器的分散配置,这通常用于实现 URL 重写、访问限制、授权和身份验证,甚至缓存策略。

虽然上述示例都可以在 Apache 主配置文件中进行配置,但 .htaccess 文件有一些重要的优势。 首先,由于每次在请求路径中找到它们时都会对其进行解释,因此它们会立即实现而无需重新加载服务器。 其次,它可以允许非特权用户控制他们自己的 Web 内容的某些方面,而无需让他们控制整个配置文件。

这为某些 Web 软件(如内容管理系统)提供了一种简单的方法来配置其环境,而无需提供对中央配置文件的访问权限。 这也被共享主机提供商用来保持对主要配置的控制,同时让客户控制他们的特定目录。

Nginx

Nginx 不解释 .htaccess 文件,也不提供任何机制来评估主配置文件之外的每个目录配置。 Apache 最初开发的时候,在单个服务器上并行运行许多异构 Web 部署是有利的,并且委派权限是有意义的。 Nginx 是在单个部署更可能被容器化并附带自己的网络配置的时候开发的,从而最大限度地减少了这种需求。 在某些情况下,这可能不如 Apache 模型灵活,但它确实有其自身的优势。

.htaccess 目录级配置系统最显着的改进是性能的提高。 对于可能允许在任何目录中使用 .htaccess 的典型 Apache 设置,对于每个请求,服务器将在指向所请求文件的每个父目录中检查这些文件。 如果在此搜索过程中找到一个或多个 .htaccess 文件,则必须读取并解释它们。 通过不允许目录覆盖,Nginx 可以通过为每个请求执行单个目录查找和文件读取来更快地为请求提供服务(假设文件是在常规目录结构中找到的)。

另一个优点是与安全相关。 分配目录级配置访问权限还将安全责任分配给个人用户,这些用户可能不被信任来很好地处理此任务。 请记住,如果这些问题引起您的共鸣,可以在 Apache 中关闭 .htaccess 解释。

文件与基于 URI 的解释

Web 服务器如何解释请求并将它们映射到系统上的实际资源是这两个服务器不同的另一个领域。

阿帕奇

Apache 提供了将请求解释为文件系统上的物理资源或可能需要更抽象评估的 URI 位置的能力。 一般来说,对于前者,Apache 使用 <Directory><Files> 块,而它利用 <Location> 块来获取更多抽象资源。

因为 Apache 从一开始就被设计为 Web 服务器,所以默认通常将请求解释为文件系统资源。 它首先获取文档根并在主机和端口号之后附加请求的部分以尝试查找实际文件。 本质上,文件系统层次结构在 Web 上表示为可用的文档树。

当请求与底层文件系统不匹配时,Apache 提供了许多替代方案。 例如,Alias 指令可用于映射到替代位置。 使用 <Location> 块是一种使用 URI 本身而不是文件系统的方法。 还有一些正则表达式变体可用于在整个文件系统中更灵活地应用配置。

虽然 Apache 能够同时在底层文件系统和其他 Web URI 上运行,但它在很大程度上倾向于文件系统方法。 这可以在一些设计决策中看到,包括使用 .htaccess 文件进行每个目录的配置。 Apache 文档 本身警告不要在请求镜像底层文件系统时使用基于 URI 的块来限制访问。

Nginx

Nginx 被创建为既是 Web 服务器又是代理服务器。 由于这两个角色所需的架构,它主要与 URI 一起工作,并在必要时转换为文件系统。

这在 Nginx 配置文件的构建和解释方式中很明显。 Nginx 不提供为文件系统目录指定配置的机制,而是解析 URI 本身。

例如,Nginx 的主要配置块是 serverlocation 块。 server 块解释被请求的主机,而 location 块负责匹配主机和端口之后的 URI 部分。 此时,请求被解释为 URI,而不是文件系统上的位置。

对于静态文件,所有请求最终都必须映射到文件系统上的某个位置。 首先,Nginx 选择将处理请求的服务器和位置块,然后将文档根与 URI 结合起来,根据指定的配置调整任何必要的内容。

这看起来很相似,但是主要将请求解析为 URIs 而不是文件系统位置允许 Nginx 更轻松地在 web、邮件和代理服务器角色中运行。 Nginx 是通过布置如何响应不同的请求模式来配置的。 Nginx 在准备好为请求提供服务之前不会检查文件系统,这解释了为什么它没有实现 .htaccess 文件的形式。

一起使用 Apache 和 Nginx

在查看了 Apache 和 Nginx 的优点和限制之后,您可能会更好地了解哪种服务器更适合您的需求。 在某些情况下,可以通过一起使用每个服务器的优势来利用它们。

这种合作关系的常规配置是将 Nginx 作为反向代理放在 Apache 前面。 这将允许 Nginx 处理所有客户端请求。 这利用了 Nginx 的快速处理速度和同时处理大量连接的能力。

对于 Nginx 擅长的静态内容,文件或其他指令将快速直接地提供给客户端。 对于动态内容,例如 PHP 文件,Nginx 会将请求代理到 Apache,然后 Apache 可以处理结果并返回呈现的页面。 Nginx 然后可以将内容传递回客户端。

这种设置适用于许多人,因为它允许 Nginx 充当分拣机。 它将处理它可以处理的所有请求,并传递它没有本机服务能力的请求。 通过减少要求 Apache 服务器处理的请求,我们可以减轻在 Apache 进程或线程被占用时发生的一些阻塞。

此配置还通过根据需要添加额外的后端服务器来促进水平扩展。 Nginx 可以配置为将请求传递给多个服务器,从而提高此配置的性能。

结论

Apache 和 Nginx 都强大、灵活且有能力。 确定最适合您的服务器很大程度上取决于评估您的特定需求并使用您期望看到的模式进行测试。

这些项目之间的差异会对原始性能、功能和在生产中使用任一解决方案所需的实施时间产生非常实际的影响。 使用最符合您的目标的解决方案。