Apache--Mpms && Nginx事件驱动

MPM 全称是多道处理模块,我们都知道 apache 是以模块化方式设计的。那 MPM 用来决定 apache 如何处理用户请求的。是通过一个进程处理一个请求,还是一个线程处理一个请求。当前MPM有三种可以选择的方式:

  • prefork
  • worker
  • event

虽然有以上三种方式,但是要注意在任何时间,必须有一个,而且只能有一个MPM被使用。下面就介绍一下这三种处理方式的区别。

prefork

在这种工作模型下,apache 进程分为 master 进程跟 worker 进程。web 服务启动就是启动 master 进程,随之 master 进程会启动若干个 worker 子进程。master 进程的工作就是管理 worker 子进程。而 worker 子进程的工作就是处理用户请求。当用户发起一个请求,apache 就会从空闲的子进程中选择一个处理这个用户请求。

这种处理方式有以下几点好处:

  • 用户不用等到其他进程处理完毕。因为只要有空闲子进程在就可以处理新的请求
  • 如果一个 worker 子进程崩溃了,不会影响其他 worker 进程处理请求。

但是 worker 子进程的个数限制于 apache 配置文件中如下几个条目的限制

  • MinSpareServers 最少空闲worker进程。
  • MaxSpareServers 最多空闲worker进程,超过这个数,就会有一些空闲 worker 进程被 kill
  • MaxRequestWorkers 同一时刻可以处理的请求数,即并发量
  • MaxConnectionsPerChild 每一个worker子进程一生中可以处理的请求,超过这个数之后就会被 master 进程 kill

同时, 一般 master 进程使用 root 用户启动,这样方便 master 进程监听 80 端口,以及管理进程。而余下的 worker 子进程则是 以apache 配置文件中 User 指令指定的用户启动。这样子是为了减少 worker 子进程的权限,保证安全。

root@ff1221aa94a9:~# ps -aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   4448   676 ?        Ss   09:33   0:00 /bin/sh -c supervisord -n
root         5  0.0  0.8  60556 17172 ?        S    09:33   0:02 /usr/bin/python /usr/bin/supervisord -n
root        31  0.0  0.1  61384  3160 ?        Ss   09:33   0:00 /usr/sbin/sshd
root        32  0.0  0.8 200164 16384 ?        Ss   09:33   0:00 /usr/local/apache/bin/httpd -k start
daemon      33  0.0  0.4 200300  8392 ?        S    09:33   0:00 /usr/local/apache/bin/httpd -k start
daemon      34  0.0  03 200300  7512 ?        S    09:33   0:00 /usr/local/apache/bin/httpd -k start
daemon      35  0.0  0.3 200300  7512 ?        S    09:33   0:00 /usr/local/apache/bin/httpd -k start
daemon      36  0.0  0.3 200300  7512 ?        S    09:33   0:00 /usr/local/apache/bin/httpd -k start
daemon      37  0.0  0.3 200300  7512 ?        S    09:33   0:00 /usr/local/apache/bin/httpd -k start

执行 ps 可以看出只有一个 master 进程以 root 用户方式启动

worker

prefork 的缺点很明显,一 个worker 进程处理一个请求,并发不会高,而且进程占用的资源太多。做的事情却只是处理一个请求。worker针对prefork的问题进行了改进。

  • 仍然有一个 master 父进程启动若干个子进程
  • 每个子进程启动若干个线程
  • 每个线程处理每个请求

这样子,worker 模型的并发性高于 prefork 模型。并且由于线程的开销小于进程,所以 worker 模型占用的资源反而小于 prefork。

但是 worker 相对于 prefork 存在一个问题:非线程安全。最典型的一个问题在于:如果你的 apache 使用了 worker 模型工作,但是 php 却使用非线程安全的版本,那么这两者就不能工作了。所以纵然 worker 有万般好,但是碰到使用非线程安全的历史代码,还是只能乖乖使用 prefork 模型。

worker 模型使用多线程响应请求,这样子存在一个问题,即一个线程崩溃就会影响整个进程。所以 worker 使用的是多进程 + 多线程的混合模型。即可以提高并发性,也可以避免一个线程崩溃导致整个整个 web 站点崩溃。

同 prefork 一样,worker 中子进程跟线程数量也受到 apache 配置文件的控制。有如下参数

  • MinSpareThreads 最少空闲线程
  • ThreadsPerChild 每个子进程可以创建的线程数量
  • MaxClients 同时可以处理的请求数
  • 。。。。。

其 web 服务调优大抵就是根据服务器配置调节这些参数。具体参数细节可以参考 Apache 文档

Event

event 模型是在 apache2.2 之后当做试验特性引入的, 在apache2.4 之后才正式支持。event 模型是为了解决长连接 (keep-alive) 问题而生的。使用 worker 模型,一个线程对应一个请求,当一个请求为长连接的时候,线程就会保持当长连接状态,等待客户端的下一个请求。这样子当前线程就不能处理其他客户端请求了。

event 模型跟 worker 模型很像,也是多个进程 + 多个线程的混合模式,但是 event 模型下每个进程会有一个单独的线程来管理这些 keep-alive 类型的线程。当新的请求过来的时候,管理线程会把请求交给其他的空闲线程处理。这样子就避免了每个线程都被 keep-alive 阻塞。

但是 event 模型并不是所有情况都通用,在https协议下会退化成worker模型。具体原因可以看官方文档

Nginx

讲到 Apache,不得不提起现在 Nginx。相比于Apache,Nginx 于2004 年正式发布,而 Apache 在 1995 就已经出现了。当时 web 环境还只是简单的展示静态页面,而且并发量远没有现在这么高。所以当时 Apache 的 prefork 模型也可以很好的承担 web 服务需求。加之其稳定性好,没有什么理由不用它。

当时后来互联网渐渐变大,网站的并发量变大,Apache 就出现了一个 C10K 的问题。即一个物理服务器达到并发量 1W 的时候 apache 就会承受不了。后来 2004 年 Nginx 很好的解决了 C10K 问题。Nginx 为何能优于 apache 解决 C10K 问题,我们还是得从其处理请求模型说起。

Nginx 有三个著名的特性:

  • 事件驱动编程
  • 异步
  • 非IO阻塞

正是这三种编程方式促使 Nginx 可以有如此高的并发量。下面来分析下 Nginx 到底是如何工作的。

同样,Nginx 的进程也分为 master 进程跟 worker 子进程。(其实还有两个 cache 有关的进程, 这里略过)。在启动 nginx 之后,master 进程就会随即创建一定数量的 worker 子进程,并且之后 worker 子进程数量保持不变。并且这些 worker 子进程都是单线程的。当一个请求到来时,worker 进程中某一个空闲进程就会去处理这个请求。乍一看到这里 nginx 的工作模式跟 apache 没有什么区别。关键就在于 nginx 如何处理用户请求。

worker 子进程开始处理请,这个请求可能是访问某个网站的静态页面。而 html 页面都是保存在硬盘上的。站在操作系统角度来看,nginx 是没有办法直接读取硬盘上的文件,必须由 nginx 告诉操作系统需要读取哪个文件,然后由操作系统去读取这个文件,读取完毕操作系统再交给 nginx。也就是说,在操作系统读取文件的时候,nginx 是空闲的。如果是 apache,那这个时候 apache 的 worker 进程/线程就阻塞在这里等待操作系统把文件读取好再交个自己,这种就称之为 IO 阻塞

但是 nginx 不一样, nginx 的 worker 进程在这个时候就会注册一个事件,相当于告诉操作系统:你文件读好了跟我说一下,我先去处理其他事情。然后这个 worker 就可以去处理新的用户请求了。这里 nginx 的 worker 进程并没有由于操作系统读取文件而阻塞等待,这种即称之为非 IO 阻塞

当操作系统读取好文件之后,就会通知 ngixn :我文件帮你读取好了,你过来拿走。"操作系统读取好文件"这个事件被触发了,于 是Nginx 就跑回去把文件拿走,然后返回响应。这种由于某个事件出现触发 Nginx 执行操作的方式就称为事件驱动编程

我们回顾上面过程,一个用户请求读取文件,nginx 把读取文件这个事情通知操作系统之后就去处理下一个用户请求,直到操作系统读取好文件之后再返回响应。这种一个请求还没有处理完毕就去处理下一个请求的编程方式即异步编程

正是由于 nginx 这种工作模型,使得 nginx 在保持一定量的 worker 进程下,也可以得到相当大的并发量。这点正是 nginx 优于 apache 的地方。同样,nginx 的这种请求处理模型在处理长连接的时候也可以使用。

Use Both

那么是不是说 Nginx 一定就优于 Apache,Apache就药丸了呢?也不是。一定要记住,一个后来者的出现, 没有在它的前辈所擅长的领域打败它,那么后来者是不可能完全取代前者。很有可能的情况是两者并存。nginx 本身并不能处理 php,python 等脚本语言,只能把这些动态请求通过 CGI 转发给其他程序处理。所以现在通常的架构是前台 Ngixn 负责处理静态文件诸如 js,css,image 文件。而碰到请求 php 等动态内容。就在后端多个 apache 服务器中选择一个比较空闲的服务器,把这请求转发给这个服务器处理。等 apache 处理好之后把返回交给 nginx,nginx 再返回给用户。这是目前典型的一种设计方案。上面的流程中nginx负责两个功能:反向代理,负载均衡。这也是 nginx 所擅长的两个功能。而 apache 丰富的模块可以很好的满足一个站点的各种需求。并且经过了 20+ 年的考验,Apache 的稳定性也是可以保证的。

web站点架构
web站点架构
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 227,488评论 6 531
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 98,034评论 3 414
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 175,327评论 0 373
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 62,554评论 1 307
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 71,337评论 6 404
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 54,883评论 1 321
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 42,975评论 3 439
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 42,114评论 0 286
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 48,625评论 1 332
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 40,555评论 3 354
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 42,737评论 1 369
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 38,244评论 5 355
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 43,973评论 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 34,362评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 35,615评论 1 280
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 51,343评论 3 390
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 47,699评论 2 370

推荐阅读更多精彩内容

  • 第一章 Nginx简介 Nginx是什么 没有听过Nginx?那么一定听过它的“同行”Apache吧!Ngi...
    JokerW阅读 32,732评论 24 1,002
  • 上一篇《WEB请求处理一:浏览器请求发起处理》,我们讲述了浏览器端请求发起过程,通过DNS域名解析服务器IP,并建...
    七寸知架构阅读 81,090评论 21 356
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,776评论 18 139
  • 什么是Nginx? Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器N...
    jiangmo阅读 2,566评论 1 9
  • 选择第一段文稿 便签I.找一段不容易被打扰的时间,然后“嵌入”日常生活中规律使用,即养成习惯。 便签A1.经过一段...
    豆子121阅读 172评论 0 1