Apache和Nginx都属于Web服务器,二者都实现了HTTP 1.1协议。不管是选择哪一个,都是根据应用场景来决定的,因此些文件仅从应用场景出发,来对比二者之间的各自特色。要让正确的工具,作出正确的事。
Web服务器也称为WWW(WORLD WIDE WEB)服务器,主要功能是提供网上信息浏览服务。php
GET /index.php HTTP/1.1 +---------------+ +----------------+ | +----> | | Browser | | Server | | <----+ | +---------------+ +----------------+ HTTP/1.1 200 OK
Apache HTTP Server是Apache软件基金会的一个开放源代码的网页服务器,能够在大多数计算机操做系统中运行,因为其跨平台和安全性。被普遍使用,是最流行的Web服务器端软件之一。它快速、可靠而且可经过简单的API扩充,将Perl/Python等解释器编译到服务器中。前端
Apache是基于模块化设计的,它的核心代码并很少,大多数的功能都被分散到各个模块中,各个模块在系统启动的时候按需载入。nginx
+----------+ +- | Module | -----------------+ | +----------+ | | +------------+ +-----------+ Apache HTTPD | php module | | Module | +------------+ +-----------+ +----------+| +----------+-------- | MPM |+ | +----+---+-+ +-v-----------+ | | | ARP <--+ | +------+------+ | | | +---------------v-------------v--+ | Operating System | +--------------------------------+
MPM(Multi -Processing Modules,多重处理模块)是Apache的核心组件之一,Apache经过MPM来使用操做系统的资源,对进程和线程池进行管理。Apache为了可以得到最好的运行性能,针对不一样的平台 (Unix/Linux、Window)作了优化,为不一样的平台提供了不一样的MPM,用户能够根据实际状况进行选择,其中最常使用的MPM有 prefork和worker两种。至于您的服务器正以哪一种方式运行,取决于安装Apache过程当中指定的MPM编译参数,在X系统上默认的编译参数为 prefork。程序员
因为大多数的Unix都不支持真正的线程,因此采用了预派生子进程(prefork)方式,象Windows或者Solaris这些支持 线程的平台,基于多进程多线程混合的worker模式是一种不错的选择。Apache中还有一个重要的组件就是APR(Apache portable Runtime Library),即Apache可移植运行库,它是一个对操做系统调用的抽象库,用来实现Apache内部组件对操做系统的使用,提升系统的可移植性。 Apache对于php的解析,就是经过众多Module中的php Module来完成的。web
+--------------------------------------------------------------+ | +---------------------+ 启动阶段 | | | 系统启动, 配置 | | | +----------+----------+ | | | | | +----------v----------+ | | | 模块的初始化 | | | +-+--------+--------+-+ | | | | | | | +-------------+ | +------v-------+| +--------------+ | | | 子进程初始化 |<+ | 子进程初始化 |+>| 子进程初始化 | | | +------+------+ +-------+------+ +-------+------+ | +--------------------------------------------------------------+ | | | | 运行阶段 | | +----v----+ +----v----+ +----v----+ | | | 请求循环 | | 请求循环 | | 请求循环 | | | +----+----+ +----+----+ +----+----+ | | | | | | | +------v------+ +------v------+ +------v------+ | | | 子进程结束 | | 子进程结束 | | 子进程结束 | | | +-------------+ +-------------+ +-------------+ | +--------------------------------------------------------------+
这个生命周期是在perfork工做下的示意,从图中能够看出,Apache对于每个请求都要启动一个单独的进程来处理。算法
一个单独的控制进程(父进程)负责产生子进程,这些子进程用于监听请求并做出应答。Apache老是试图保持一些备用的 (spare)或是空闲的子进程用于迎接即将到来的请求。这样客户端就无需在获得服务前等候子进程的产生。在Unix系统中,父进程一般以root身份运行以便邦定80端口,而 Apache产生的子进程一般以一个低特权的用户运行。User和Group指令用于配置子进程的低特权用户。运行子进程的用户必需要对他所服务的内容有读取的权限,可是对服务内容以外的其余资源必须拥有尽量少的权限。数据库
每一个进程可以拥有的线程数量是固定的。服务器会根据负载状况增长或减小进程数量。一个单独的控制进程(父进程)负责子进程的创建。每一个子进程可以创建ThreadsPerChild数量的服务线程和一个监听线程,该监听线程监听接入请求并将其传递给服务线程处理和应答。Apache老是试图维持一个备用(spare)或是空闲的服务线程池。这样,客户端无须等待新线程或新进程的创建便可获得处理。在Unix中,为了可以绑定80端口,父进程通常都是以root身份启动,随后,Apache以较低权限的用户创建子进程和线程。User和Group指令用于配置Apache子进程的权限。虽然子进程必须对其提供的内容拥有读权限,但应该尽量给予他较少的特权。另外,除非使用了suexec ,不然,这些指令配置的权限将被CGI脚本所继承。apache
这是Apache最新的工做模式,它和worker模式很像,不一样的是在于它解决了keep-alive长链接的时候占用线程资源被浪费的问题,在event工做模式中,会有一些专门的线程用来管理这些keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务器的线程,执行完毕后,又容许它释放。这加强了在高并发场景下的请求处理。在*unix系统中的apache2.4版本使用的就是这个模式。后端
在启动阶段,Apache主要进行配置文件解析(例如http.conf以及Include指令设定的配置文件等)、模块加载(例如mod_php.so,mod_perl.so等)和系统资源初始化(例如日志文件、共享内存段等)工做。在这个阶段,Apache为了得到系统资源最大的使用权限,将以特权用户root(X系统)或超级管理员administrator(Windows系统)完成启动。浏览器
+--------+ | 开始 | +----+---+ | +----------v------------+ 解析主配置文件http.conf中配置信息, | 解析配置文件 | 像LoadModule, AddType +----------+------------+ 等指令被加载至内存 | +----------v------------+ 依据AddModule, LoadModule等指令 | 加载静态/动态模块 | 加载Apache模块,像mod_php5.so被 +----------+------------+ 加载至内存,映射到Apache地址空间。 | +----------v------------+ 日志文件、共享内存段,数据库连接 | 系统资源初始化 | 等初始化 +----------+------------+ | +---v----+ | 结束 | +--------+
在运行阶段,Apache主要工做是处理用户的服务请求。在这个阶段,Apache放弃特权用户级别,使用普通权限,这主要是基于安全性的考虑,防止因为代码的缺陷引发的安全漏洞。
因为Apache的Hook机制,Apache 容许模块(包括内部模块和外部模块,例如mod_php5.so,mod_perl.so等)将自定义的函数注入到请求处理循环中。mod_php5.so/php5apache2.dll就是将所包含的自定义函数,经过Hook机制注入到Apache中,在Apache处理流程的各个阶段负责处理php请求。
Apache将请求处理循环分为11个阶段,依次是:Post-Read-Request,URI Translation,Header Parsing,Access Control,Authentication,Authorization,MIME Type Checking,FixUp,Response,Logging,CleanUp。
Apache处理http请求的生命周期
Nginx(发音同engine x)是一款由俄罗斯程序员Igor Sysoev所开发轻量级的网页服务器、反向代理服务器以及电子邮件(IMAP/POP3)代理服务器。起初是供俄国大型的门户网站及搜索引擎Rambler(俄语:Рамблер)使用。
Nginx由内核和模块组成,其中,内核的设计很是微小和简洁,完成的工做也很是简单,仅仅经过查找配置文件将客户端请求映射到一个location block(location是Nginx配置中的一个指令,用于URL匹配),而在这个location中所配置的每一个指令将会启动不一样的模块去完成相应的工做。
+ ^ Http Request | | Http Response | | +---------+------v-----+ +----+----+ | Conf | Nginx Core | | FilterN | +---------+------+-----+ +----^----+ | | | +----+----+ | | Filter2 | choose a handler | +----^----+ based conf | | | +----+----+ | | Filter1 | | +----^----+ | | Generate content +-----v--------------------+----+ | Handler | +-------------------------------+
Nginx自己作的工做实际不多,当它接到一个HTTP请求时,它仅仅是经过查找配置文件将这次请求映射到一个location block,而此location中所配置的各个指令则会启动不一样的模块去完成工做,所以模块能够看作Nginx真正的劳动工做者。一般一个location中的指令会涉及一个handler模块和多个filter模块(固然,多个location能够复用同一个模块)。handler模块负责处理请求,完成响应内容的生成,而filter模块对响应内容进行处理。
上图是Nginx的架构,这个架构相似于Apache的Worker工做状态,Nginx的每个Worker进程都管理着大量的线程,真正处理请求的是Worker之下的线程。
全部实际上的业务处理逻辑都在worker进程。worker进程中有一个函数,执行无限循环,不断处理收到的来自客户端的请求,并进行处理,直到整个nginx服务被中止。Worker中这个函数执行内容以下:
FastCGI是一个可伸缩地、高速地在HTTP server和动态脚本语言间通讯的接口。多数流行的HTTP server都支持FastCGI,包括Apache、Nginx和lighttpd等。同时,FastCGI也被许多脚本语言支持,其中就有PHP。
FastCGI是从CGI发展改进而来的。传统CGI接口方式的主要缺点是性能不好,由于每次HTTP服务器遇到动态程序时都须要从新启动脚本解析器来执行解析,而后将结果返回给HTTP服务器。这在处理高并发访问时几乎是不可用的。另外传统的CGI接口方式安全性也不好,如今已经不多使用了。
FastCGI接口方式采用C/S结构,能够将HTTP服务器和脚本解析服务器分开,同时在脚本解析服务器上启动一个或者多个脚本解析守护进程。当HTTP服务器每次遇到动态程序时,能够将其直接交付给FastCGI进程来执行,而后将获得的结果返回给浏览器。这种方式可让HTTP服务器专注地处理静态请求或者将动态脚本服务器的结果返回给客户端,这在很大程度上提升了整个应用系统的性能。
Nginx不支持对外部程序的直接调用或者解析,全部的外部程序(包括PHP)必须经过FastCGI接口来调用。FastCGI接口在Linux下是socket(这个socket能够是文件socket,也能够是ip socket)。
Nginx和Apache同样,都是HTTP服务器软件,在功能实现上都采用模块化结构设计,都支持通用的语言接口,如PHP、Perl、Python等,同时还支持正向和反向代理、虚拟主机、URL重写、压缩传输、SSL加密传输等。
因为Nginx和Apache各自的优点,如今不少人选择了让二者在服务器中共存。在服务器端让Nginx在前,Apache在后。由Nginx作负载均衡和反向代理,而且处理静态文件,将动态请求(如PHP应用)交给Apache去处理。
做者:未知
原文: https://blog.csdn.net/pkgray/...