设为首页 收藏本站
查看: 885|回复: 0

[经验分享] Apache服务器中prefork和worker工作模式

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2014-7-30 08:27:58 | 显示全部楼层 |阅读模式
一、多道处理模块MPM介绍
    Apache HTTP 服务器被设计为一个功能强大,并且灵活的 web 服务器, 可以在很多平台与环境中工作。不同平台和不同的环境往往需要不同 的特性,或可能以不同的方式实现相同的特性最有效率。Apache 通过模块化的设计来适应各种环境。这种设计允许网站管理员通过在 编译时或运行时,选择哪些模块将会加载在服务器中,来选择服务器特性。        Apache 2.0 扩展此模块化设计到最基本的 web 服务器功能。 它提供了可以选择的多处理模块(MPM),用来绑定到网络端口上,接受请求, 以及调度子进程处理请求。
    在用户看来,MPM 很像其它 Apache 模块。主要是区别是,在任何时间, 必须有一个,而且只有一个 MPM 加载到服务器中。
二、选择MPM

    MPM 必须在编译前,配置时指定,然后编译到服务器程序中。 仅当编译器知道使用了线程时,它才有能力优化许多函数。
    为了使用指定的 MPM,请在执行 configure 时,使用参数 --with-mpm=NAME。NAME 是指定的 MPM 名称,我们只可以指定其中一个MPM模块。
编译完成后,可以使用 ./httpd -l 来确定选择的 MPM。 此命令会列出编译到服务器程序中的所有模块,包括 MPM。 Unix/Linux支持三种MPM, Prefork, worker, event,其中event模型在apache2.2版本是测试版,不建议在生产环境中使用,到apache2.4,event模型是稳定版。


可以使用 httpd -l 来确定选择的 MPM。 此命令会列出编译到服务器程序中的所有模块,包括 MPM。

1
2
3
4
5
6
[iyunv@localhost ~]# httpd -l
Compiled in modules:
  core.c            # 核心
  prefork.c         # 编译的MPM模块
  http_core.c
  mod_so.c          # 支持DSO动态模块加载




prefork
    prefork 为多路模块MPM 实现了一个进程模型,预派生的web服务器。prefork 适用于没有线程安全库,需要避免线程兼容性问题的系统。它是要求将每个请求相互独立的情况下最好的MPM,这样一个请求出现问题,不至于影响其他的请求。
      prefork模式使用多个子进程,每个子进程在某个确定的时间只能维持一个连接。在大多数平台上,Prefork MPM在效率上要比Worker MPM 要高,但是内存使用大的多。prefork在Linux下工作,比worker更有优势。
    一个单独的控制进程(父进程)负责生产子进程,这些子进程用于监听请求并作出应答。apache 总是试图保持一个备用的(spare)或是空闲的子进程用于迎接即将到来的请求。这样客户端就无需在得到服务前等候子进程的产生。在unix系统中,父进程通常是以root 身份运行以便绑定80端口,而apache生产的子进程通常一个低特权的用户运行。User和Group指令用于配置配置子进程的低特权用户。运行子进程的用户必须要对他所服务的内容用读取的权限,但是对服务内容之外的其他资源必须拥有尽可能少的权限
    当httpd服务启动之后,会启动一个主进程(master process),它负责监听用户请求,以及派生和销毁子进程。它并不处理用户请求,一旦请求来了之后,调度其子进程(work process)来响应,然后继续监听其他请求。

    需要考虑的是:刚启动的时候,创建多少空闲进程呢?为了快速响应用户请求,会创建几个空闲进程,当请求来了,可以快速的响应。如果请求太多,那么则会派生更多的进程来响应请求,但是假设到了晚上,访问量不大时,我们应该把多余的空闲进程回收,以免占用资源。

master process的主要作用:
1、启动服务时绑定特权端口
2、派发和回收子进程
3、读取分析主配置文件
4、监听用户请求并且调度子进程来响应

配置:编辑主配置文件 /etc/httpd/conf/httpd.conf

1
2
3
4
5
6
7
8
9
# prefork MPM
<IfModule prefork.c>     # 判断是否有prefork.c这个模块,有就生效,否则无效
StartServers       8     # 默认启动的工作进程数
MinSpareServers    5     # 保持的最少空闲进程数
MaxSpareServers   20     # 保持的最大空闲进程数
ServerLimit      256     # 保持的最大活动进程数
MaxClients       256     # 最大并发连接数
MaxRequestsPerChild  4000     # 每个子进程在生命周期能服务的最大请求数
</IfModule>



    IfModule指令,意为判断模块是否存在,如果存在那么参数则生效,反之如果不存在此模块,参数将不会生效。
StartServer 5
   指定服务器启动是建立的子进程的数量,prefork 默认为5。为了满足MinSpareServers设置的需要创建一个进程, 等待一秒钟,继续创建两个,再等待一秒钟,继续创建四个……如此按指数级增加创建的进程数,最多达到每秒32个,直到满足 MinSpareServers设置的值为止。这就是预派生 (prefork)的由来。这种模式可以不必在请求到来时再产生新的进程,从而减小了系统开销以增加性能。
MinSpareServers 5
     指定空闲子进程的最小数量,默认为5。假如当前空闲子进程数少于MinSpareServers,那么apache 将以每秒一个的速度产生新的子进程。此参数不要设置的太大
MaxSpareServers
      设置空闲进程的最大数量,默认为10。如果当前有超过MaxSpareServers数量的空闲子进程,那么父进程将杀死多余的子进程。此参数不要设置过大。如果该参数设置比MinSpareServers小,apache将会自动将其修改成"MinSpareServers+1”。如果站点负载较大,可考虑同时加大MinSpareServers和MaxSpareServers。
MaxClients 256
       限定同一时间客户端最大接入的数量(单个进程并发线程数)。默认为256,任何超过MaxClients限制的请求都会进入等候队列,一旦一个链接被释放,队列中的请求将得到服务。如果要增大这个值,必须同时增加ServerLimit.理论上来说这个值越大,性能就越好。
ServerLimit 256
   默认的MaxClient最大是256个线程,假如想设置更大的值,就需要加上ServerLimit这个数。 200000是ServerLimit这个参数的最大值。假如需要更大,则必须编译apache,此前都是无需重新编译apache。生效前提是,必须放在其他指令的前面。
MaxRequestsPerChild
       每个子进程在其生存期内允许伺服的最大请求数量。默认为10000到达MaxRequestsPerChild的限制后,子进程将会结束。
       如果MaxRequestsPerChild 为0,子进程将永远不会结束。将MaxRequestsPerChild 设置成非零值有两个好处:
  • 可以防止(偶然的)内存泄漏无限进行,从而耗尽内存。
  • 给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量。

    对于KeepAlive链接,只有第一个请求会被计数。事实上,它改变了每个子进程限制最大链接数量的行为。

我们看看httpd进程:

1
2
3
4
5
6
7
8
9
10
[iyunv@localhost ~]# ps -ef | grep httpd
root      1812     1  0 10:00 ?        00:00:01 /usr/sbin/httpd        # master process
apache    1814  1812  0 10:00 ?        00:00:00 /usr/sbin/httpd        # 以下都是
apache    1815  1812  0 10:00 ?        00:00:00 /usr/sbin/httpd        # work process
apache    1816  1812  0 10:00 ?        00:00:00 /usr/sbin/httpd
apache    1817  1812  0 10:00 ?        00:00:00 /usr/sbin/httpd
apache    1818  1812  0 10:00 ?        00:00:00 /usr/sbin/httpd
apache    1819  1812  0 10:00 ?        00:00:00 /usr/sbin/httpd
apache    1820  1812  0 10:00 ?        00:00:00 /usr/sbin/httpd
apache    1821  1812  0 10:00 ?        00:00:00 /usr/sbin/httpd



    Prefork是一个进程处理一个请求,在启动httpd的时候,如果选择的是这种模式,会首先创建一个主进程(控制进程)和StartServers个子进程,可以看到StartServers为8个.由于进程和进程之间是独享内存的,所以一个进程崩溃了不会影响到其他的进程,所以Prefork模式的稳定性比较好,但是进程多了消耗的内存会比较大.
    主进程在创建了StartServers个子进程后,为了满足MinSpareServer的设置需求,会先创建一个进程,等待一秒,创建二个进程,再等待一秒,创建四个进程....以几何数增加创建的进程,最多达到每秒创建32个,直到满足MinSpareServer的设置(可以看到以下的MinSpareServer为5),这就是预派生(Prefork)的由来,这样不必等到有请求到来时才花时间创建新的进程,提高了系统响应速度以增加性能.


worker
    worker MPM 使用多个子进程,每个子进程有多个线程。每个线程在每个确定的时间只能维持一个连接。通常来说,在一个高流量的HTTP服务器上,Worker MPM 是个比较好的选择,因为Worker MPM 的内存使用比Prefork MPM 要低的多。但是worker MPM 也有缺陷。如果一个线程崩溃,整个进程就会连同其任何线程一起“死掉”,由于线程共享内存空间,所以一个程序在运行时必须被系统识别为 “每个线程都是安全的”。
    当第一个用户请求到达的时候线程发现需要复制文件,通过内核将文件复制给其进程,所以第二个用户请求同一个文件,对于第二个线程来说这个文件已存在,因为是公用同一个空间,所以速度得到提升;
    其缺点:线程很有可能产生资源争用,并不是全状态并行。所以一个进程里不能启动太多线程,所以可启动多个进程从其启动的进程再启多个线程,但无论如何每个线程也都是一个独立的执行实体(执行必须给cpu资源)
更改apache的MPM为woker模式
    我们是通过yum安装的httpd,它默认已经编译了prefork, worker两个MPM,所以我们可以切换。如果是手动编译的话, 我们仅能指定一个--with-mpm=NAME。

编辑配置文件/etc/sysconfig/httpd:
1
2
3
4
5
6
# vi /etc/sysconfig/httd
# 把下面这一行的注释去掉
HTTPD=/usr/sbin/httpd.worker

# 切换模式必须重启服务
# service httpd restart



worker默认的配置:
1
2
3
4
5
6
7
<IfModule worker.c> 如果有这个模块就启用
StartServers         4         # 启动的子进程数
MaxClients         300         # 并发请求最大数
MinSpareThreads     25         # 最小空闲线程数 total
MaxSpareThreads     75         # 最大空闲线程数 total
ThreadsPerChild     25         # 每个子进程可生成的线程数
MaxRequestsPerChild  0         # 每个子进程可服务的最大请求数,0表示不限制



1
2
3
4
5
[iyunv@localhost ~]# ps -ef | grep httpd
root      2395     1  0 15:36 ?        00:00:00 /usr/sbin/httpd.worker     
apache    2397  2395  0 15:36 ?        00:00:00 /usr/sbin/httpd.worker
apache    2398  2395  0 15:36 ?        00:00:00 /usr/sbin/httpd.worker
apache    2399  2395  0 15:36 ?        00:00:00 /usr/sbin/httpd.worker



    worker的工作原理是,由主控制进程生成“StartServers”个子进程,每个子进程中包含固定的ThreadsPerChild线程数,每个线程处理一个请求,线程是共享内存空间的,所以一个线程崩溃会导致在这个进程下的所有线程都崩溃,所以他的稳定性没有Prefork好,但是内存使用率比Prefork低。同样,为了不在请求到来时再生成线程,MinSpareThreads和MaxSpareThreads设置了最少和最多的空闲线程数;而MaxClients设置了所有子进程中的线程总数。如果现有子进程中的线程总数不能满足负载,控制进程将派生新的子进程。
  MinSpareThreads和MaxSpareThreads的最大缺省值分别是25和75。这两个参数对Apache的性能影响并不大,可以按照实际情况相应调节。
    ThreadsPerChild是worker 中影响性能最重要的一个指标,Worker模式下所能同时处理的请求总数是由StartServers总数乘以ThreadsPerChild的值决定的,应该大于等于MaxClients



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-22886-1-1.html 上篇帖子: Win2003+apache+PHP+SqlServer2008 配置 下篇帖子: Apache虚拟主机配置 服务器
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表