Apache vs Nginx:基于实践经验的比较(外文翻译)

本文来自Mobingi官方技术专栏,欢迎关注php

原文地址:Apache vs Nginx: Practical Considerations 前端

简介

Apache和Nginx是世界上两个最流行的开源web服务器,他们一块儿支撑了互联网上超过50%流量。他们两个都支持多种负载模式而且能够和其余软件服务集成在一块儿提供全栈的web解决方案。nginx

虽然Apache和Nginx有不少共同点,但你不该该认为它们是能够彻底等价交换的。它们都·有本身各自的长处,了解这些有助于你从新评估你的web服务器的选择。这篇文章致力于讨论这两个服务器在不一样领域的不一样表现。web

概览

在咱们深刻讨论Apache和Nginx的不一样以前,让咱们先简单回顾一下这两个项目的背景和特性。正则表达式

Apache

Apache HTTP 服务器于1995年由Robert McCool在Apache软件基金会(1999创立)的领导下开发出来。由于它是这个基金会的原创项目而且也是这个基金会到目前为止最有名的软件,因此它常常被称作“Apache”。算法

Apache从1996年开始直到如今一直是互联网上最流行的web服务器软件。由于流行,Apache基金会能够经过提供完善的文档以及系统集成支持给其余软件项目来获取收益。apache

由于Apache的灵活性,性能和普遍支持,它常常被系统管理员选择做为web服务器。它能够经过动态加载模块拓展功能,而且能够在不链接其余第三方软件的状况下执行多种解释型语言。后端

Nginx

在2002年,Igor Sysoev开始着手写Nginx服务器用来解决C10K问题。C10K问题是web服务器的一个挑战,要求一个web服务器在同一时刻能够处理10000个链接请求。Nginx于2004年发布最新版本,使用一种非同期的、基于事件处理机制来知足这一需求。缓存

由于占用不多资源而且很是容易使用底端硬件扩展,Nginx开始变得流行。Nginx擅长提供静态内容,而且被设计为将须要动态内容处理的求转发给其余软件以解决10K问题。安全

Nginx常常因为它的低资源消耗以及高负载能力被服务器管理员选中,它的拥护者很是欢迎Nginx聚焦在web服务器以及代理服务器的核心特性上。

链接处理方式

Apache和Nginx的一个巨大的差距是他们实际处理链接和请求的方式。在不一样的网络流量条件下,这产生了两个服务器很是不一样的表现。

Apache

Apcahe提供了多种多进程工做模式(Apache称这些为MPMs, multi-processing modules)来处理请求,基本上,这样可让管理员很容易地变换服务器处理链接的方式。这些模式以下:

  • mpm_prefork:这种模式为每个请求建立一个处理它的进程。每一个子进程同一时间只处理一个请求。若是请求数量小于进程数量,这种模式运行的很是快。不过当须要处理请求超出进程数量时,性能降低很是严重,因此对于不少应用场景这种模式不是一个好的选择。每个进程都会耗损至关的内存,因此这种工做模式很难优化。当处理请求的内部组件不支持线程工做模式的状况下,这种模式可能仍然是一个好的选择。好比,PHP就不是线程安全的,因此这种工做模式被推荐为与mod_php一块儿运行的惟一安全模式。

  • mpm_worker: 这种模式建立的进程能够管理本身线程。每个线程能够单独处理一个链接。由于与进程相比系统能够建立更很是多的线程,也就意味着这种模式比prefork模式能处理更多的链接。一个新的链接会被立刻处理,而不须要等待一个空闲的进程来处理。

  • mpm_event: 这种模式和worker模式很像,不过它优化了keep-alive请求的处理方式。当使用worker模式的时候,一个链接(connection)会持有一个线程直到这个链接失效,无论这个链接上是否有请求过来。在event模式下,有专门的线程用来处理和保持链接,而后将请求转发给其余线程处理。这种方式可让系统逃脱处理大量keep-alive请求的泥潭,使请求处理器获得更快的执行。这个模式在Apache2.4版本中已被标记为稳定(stable)状态。

就像你看到的,Apache提供了一个灵活的结构能够配置不一样的链接和请求处理算法。这些工做模式表明了服务器的功能演进以及伴随着互联网格局变化而来的对大并发处理的需求的增加。

Nginx

Nginx在Apache以后来到这个舞台,与生俱来就意识到须要面对大并发问。利用这方面的认识,Ngeix完全地由内到外地使用了非同期,非阻塞和事件驱动的链接处理算法。

Nginx生成工做进程,每个工做进程能够处理上千个链接。工做进程经过实现一个快速的循环算法不断的获取并处理事件。从链接中分离出实际的请求处理工做,让每个工做进程只有当新的事件发生是才与一个链接产生联系。

全部被工做进程处理的链接被放在事件循环(event loop)里面,在这个循环里,事件被非同期处理,使得处理变成一个非阻塞的过程。当链接关闭,链接从这个循环中删除。

这种链接方式使得Nginx能够利用有限的计算资源处理难以想象的大量请求。由于服务器是单线程的而且并不为处理一个新的链接生成一个单独的进程,因此内存和CPU的消耗趋于保持相对一致,甚至是在大并发的状况下也如此。

静态内容VS动态内容

在实际应用方面,Apache和Nginx之间最多见的比较是但请求到来时它们各自处理静态内容和动态内容的方式。

Apache

Apache使用传统的基于文件的方式处理静态内容的请求。它的性能主要取决于它是被设定成哪工做模式(上面提到的)。

Apache也能够处理动态内容,它经过嵌入一种处理语言到运行实例,在服务器内部就能够处理动态内容,而不须要依赖外部组建。它经过使用可动态加载的模块来开启处理动态内容的进程。

Apache的可在服务器内部处理动态内容的能力意味着配置动态处理进程也比较简单。不须要和一个附加的软件交互而且当内容处理的需求发生变化时模块也很容易替换。

Nginx

Ngnix自己没有任何的动态处理能力。若是想执行PHP代码或者为请求生成动态内容,Nginx必须将请求传递给一个外部的处理器并等待渲染好的内容(一般是HTML文档)而后再把它转发给客户端。

对于服务器管理员来讲,这个意味着你必须配置Nginx和外部处理器之间的交互,这种交互必须基于一种Nginx能理解的协议(http, FastCGI, SCGI, uWSGI, memcache)。这可能会使事情变得稍微复杂,特别是试图占用容许链接的最大值时,由于已有了一个额外的链接用来转发请求处处理器。

无论怎么说,这个模式同时也有一些优势。由于动态解释器不是嵌入到Nginx的工做进程中的,因此它的开销只限于处理动态内容,而静态内容请求会被直接处理,Nginx只在须要的时候链接程序解释器。Apache也能够这样工做,不过这样的话就失去了咱们在前面说的优势。

分布式配置VS集中配置

对于服务器管理员来讲,两个服务器表现出来的最明显的不一样是是否容许文件夹级别的配置。

Apache

apache提供一个选项,容许对每一个目录设置附加的配置。这个功能基于监测和实时翻译内容所在文件夹上一个隐藏文件中的指令来完成。这个文件就是你们所熟知的.htacess。

由于.htacess文件就存在于请求内容所在文件夹。当处理一个请求的时候,Apache检查每个文件的路径,查找.htacess文件,执行里面的命令,这使服务器的分散配置成为可能。这个功能常常用于重写URL,控制访问甚至是缓存策略。

虽然上面说的例子能够在Apache的主配置文件中设置。可是.htacess有一些重要的优点。首先,Apache在每次请求来的时候解释指令,因此.htacess的配置会当即生效,而无需重启服务器。其次它容许无权限的用户来控制他们本身的web内容的某些方面,而无需修改Apache主配置文件。

这给某些web软件,如内容管理系统(cms)提供了简单方式来配资它们本身,而无需访问主配置文件。这也一样被用于共享主机提供商使他们在保持控制主要配置文件的同时让客户对他们本身的特定目录有控制权限。

Nginx

nginx不会即时解释.htacess文件,也不提供在主配置文件以外的任何支持目录级别配置的技术。这可能相对于apache来讲不够灵活,但它却有本身的优点。

最被你们熟知的相对于基于.htacess机制实现目录级别配置的系统优点就是提升了性能。例如一个典型的Apache配置可能容许配置.htaccess在任何目录,这样的话每个请来访问任何一个目录下的资源的时候,服务器都会检查这个目录以及它全部的父目录的.htaccess文件,若是在这个过程当中有一个或者多个.htaccess文件被找到,他们必须被读取并解释执行。Nginx不容许目录重写技术,每个请求过来Nginx只查找和读取一个文件(假设文件能够在约定目录结构下找到),因此Nginx处理请求更快。

另外一个优点是关于安全的。分散的目录级别的配置也同时把安全配置web服务的责任分散到了每个用户(web应用管理员)头上,他们可能没法胜任这个任务。确保服务器管理员控制整个web服务器可预防一些把控制权转交给他人所形成的安全隐患。

若是这些观点与你产生共鸣,你应该时刻考虑是否能够关闭解释执行.htaccess文件。

文件VS基于URI的解释执行

web服务器是如何解释执行一个请求以及如何查找到与请求所匹配的系统资源的?这是另外一个这两个服务器的不一样之处。

Apache

Apache提供一种能够把请求转换成文件系统上的物理资源或者一个更抽象的URI的能力。整体上,之前的Aapache使用 或者块配置,同时使用块配置更抽象的资源。

由于Apache彻底是为web服务器所设计。默认状况下一个请求一般被解释成一个文件资源请求。它在查找请求路径中去掉域名和端口号后相对于document root的路径下的真实文件。默认状况下,文件结构会被以文档树的形式展现。

当请求没有匹配到文件资源时,Apache提供不少可选项处理这种状况。好比,一个alias命令可让请求关联到另外一个位置。用块可使用URI代替文件系统工做。固然还可使用正则表达式,从而使基于文件系统的资源查找更加灵活。

虽然Apache同时具备操做底层文件系统和网站空间的能力,可是它很是依赖于文件系统,包括使用.htacces文件实现目录级配置这,均可以被看做它的设计哲学。Apache docs警告用户当请求能够映射到底层文件系统时,最好不要使用基于URI的配置限制访问。

Nginx

Nginx被当作web服务器和代理服务器而创造。考虑这两种角色所须要的架构,它主要基于URI工做。只在须要的时候在将请求映射到文件系统。这能够被看做是构造和解释执行Nginx配置的方式。Nginx不提供任何关于文件系统目录的配置,取而代之的是解析URI自己。

举个例子,Nginx主要的配置块是server和location块。server配置块用来解释请求的域名部分,同时location配置块负责匹配URI中域名和端口号后面的的部分。从这个观点看,请求被解释成一个URI请求,并非一个映射到文件系统上的文件。

对于静态文件,全部的请求最终会映射到文件系统上的一个文件。首先,Nginx找到用于处理这个请求的server配置块和location配置块,而后组合document root目录和URI,再根据指定配置作任何须要的调整。

这可能看起来很简单,可是解析请求成URI而不是文件系统路径使得Nginx能跟简单地以web、mail和代理服务器方式工做,经过简单的配置就以对应不一样模式的request请求。Nginx不会检查文件系统直到准备好提供被请求的内容,这解释了为何它没有实现一种相似.htaccess的配置方式。

模块

Nginx和Apache都支持经过模块扩展服务器,可是他们的工做方式很是的不一样。

Apache

Apache的模块系统容许你在服务器的运行期间动态的加载或者卸载模块。Apache的核心始终存在,而模块能够打开或关闭,以添加或者删除挂载到server的主程序部分的附加功能。Apache经过这一个功能完成不少任务。因为Apache平台很是成熟,有不少用于扩展Apache的模块存在。他们能够用于改变Apache的一部分核心功能,例如mod_php就能够嵌入PHP处理器到每个运行的工做进程中。

模块不只仅只限于处理动态内容,它们还被用于URL重写,认证客户端,硬件化服务器,日志,缓存,压缩,代理,速率控制和编码等等。动态模块能够很容容易的扩展核心功能而且并不须要太多额外的工做。

Nginx

Nginx也实现了一个模块系统,可是它与Apache的实现方式很不一样。在Nginx中,模块不是动态加载的,它们必须被编译到Nginx的核心程序中。

对于不少用户来讲,这可能让他们感受Nginx不够灵活。尤为对那些只会安装发布版本而不熟悉经过编译来管理维护本身软件的用户来讲,这确实是一个问题。不过发布版本老是倾向于包含使用最普遍的模块,若是你须要一个非标准的模块,你必需要本身编译你的Nginx服务器软件。

编译Nginx的模块仍是很是有用的,他们容许指出哪些功能你不想放在服务器中,而哪些功能你须要使用。不少用户也认为这样更加安全,由于那些未经挑选的组件不会挂载到服务器中。无论怎样,若是你的服务器已经配置好了,它极可能是妥协后的产物。

Nginx模块的功能不少都和Apache模块类似。例如,Nginx模块能够提供代理服务,压缩,速率控制,日志,重写,地理位置,认证,编码,流媒体和邮件功能。

支持、兼容性、生态系统和文档

考虑这些的要点在于,你的应用主要作什么样的处理,须要配合哪些其余软件使用。

Apache

由于Apache已经流行了很长时间,对它的支持几乎是广泛存在的。有不少官方的或者第三方的文档说明核心服务器以及如何挂载其余软件到核心服务器。

Nginx

由于Nginx的高性能,愈来愈多的用户选择使用Nginx,愈来愈来越多的软件开始支持Nginx。可是在不少关键领域Nginx还须要追赶Apache的脚步。

在过去,找到一份全面的关于Nginx的文档很难。由于大部分早期的开发是由俄罗斯人完成,文档也是俄语的。伴随着这个项目的普及,产生了不少文档,而且在Nginx的网站以及第三方站点上有很是多的管理员资源。

出于对第三方软件的尊重,技术支持文档变得更加易读,而且Nginx软件包维护者开始在某些状况下容许Apache和Nginx之间配置的自由转换。就算没有技术支持,配置Nginx服务器和可选软件一块儿工做也一般很是简单直接,正如它项目文档里描述的那样。

Apache和Nginx一块儿使用

在咱们了解了Apache和Nginx的优点和劣势以后,你可能已经想好了哪个服务器更符合你的需求。不管如何,不少用户发现能够经过同时使用它们而得到它们两个的全部优势。

这种组合的传统配置是把Nginx配置到Apache的前端做为一个反向代理服务器。这使Nginx处理来自客户端的全部请求。这样得益于Nginx的快速处理能力,能够同时处理很是大量的链接。

对于Nginx擅长静态内容,文件会快速且直接的发送给客户端。对于动态内容,好比PHP文件,Nginx将把请求发送给Apache,Apache能够处理请求,并渲染结果。而后Nginx能够将结果发回给客户端。

这种设置在大多数状况下都工做的很好。由于这让Nginx像一台排序机器同样工做,Nginx会处理全部的请求而后把它不能处理的请求转发出去,经过减小Apache处理的请求数量,能够缓解当Apache的处理进程或者线程被占用时产生的阻塞。

这样配置也使你能够根据需求添加额外的后端服务器来扩容服务器。Nginx能够很容易的配置成转发请求到服务器池,这样能够加强服务器性能和容错能力。

总结

正如你看到的,Apache和Nginx都是强大,灵活的服务器软件。哪一个服务器最好,取决于你的应用服务的特殊需求,以及对它们在你指望的运行条件下的测试结果。

在两个服务器以前存在着不少不一样,这些差别的存在会实实在在地影响性能,负载,以及配置应用运行起来的时间成本。然而,这是一系列权衡结果,不该该被随意决定。最后我要说,没有万能的web服务器,因此选择适合你的项目的解决方案。


这是我第一次翻译英文文档,不少词汇找不到合适的中文表达,也可能有一些专业技术词汇没有和中文技术词汇精确对应,请你们多多指正。

相关文章
相关标签/搜索