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

[经验分享] Apache HTTP Server 中prefork和worker工作模式(二)

[复制链接]

尚未签到

发表于 2018-11-22 11:10:19 | 显示全部楼层 |阅读模式
  

  
一、多道处理模块 MPM
      Apache HTTP 服务器被设计为一个功能强大,并且灵活的 web 服务器, 可以在很多平台与环境中工作。不同平台和不同的环境往往需要不同的特性,或可能以不同的方式实现相同的特性最有效率。Apache 通过模块化的设计来适应各种环境。这种设计允许网站管理员通过在编译时或运行时,选择哪些模块将会加载在服务器中,来选择服务器特性。        
      Apache 2.0 扩展此模块化设计到最基本的 web 服务器功能。 它提供了可以选择的多处理模块(MPM),用来绑定到网络端口上,接受请求, 以及调度子进程处理请求。

       MPM的设计,带来两个重要的好处:


  •   Apache 能更优雅,更高效率的支持不同的平台。
  •   Apache 能更好的为有特殊要求的站点定制。例如,要求更高伸缩性的站点可以选择使用线程的 MPM,即 workerevent;需要可靠性或者与旧软件兼容的站点可以使用 prefork
    在用户看来,MPM 很像其它 Apache 模块。主要是区别是,在任何时间, 必须有一个,而且只有一个 MPM 加载到服务器中。



二、选择 MPM
    MPM 必须在编译前,./configure 配置时指定,然后编译到服务器程序中。 仅当编译器知道使用了线程时,它才有能力优化许多函数。

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

  • prefork    多进程模型
    预先生成进程,一个请求用一个进程处理。优点:稳定可靠,任何一个进程崩溃都不会影响其他进程;缺点:性能差,特别是并发量非常大时,非常消耗内存资源,会有大量的进程切换。
  • worker    多线程模型
    基于线程,启动多个进程,每个进程中生成多个线程。进程负责响应请求,而线程负责处理请求。因为linux不是原生支持线程,线程同步模型复杂,必须处理锁争用的问题,所以在Linux上不建议。测试发现,在linux系统上,worker 的效率并没有 prefork 高。这是默认不是worker的原因。
  • event    IO多路复用,基于事件驱动的模型。一个进程处理多个套接字,一个进程同时处理多个请求。在httpd 2.2 版本中属于测试版,在apache 2.4 之后是稳定版,强烈推荐。
     
      可以使用 httpd -l 来确定当前选择的 MPM。 此命令会列出静态编译到服务器程序(modules compiled into the server)中的所有模块,包括 MPM。

# -l Output a list of moudles compiled into the server. This will not list dynamically l# oaded modules included using the LoadModule directive.
[root@localhost ~]# httpd -l
Compiled in modules:
  core.c           # 核心
  prefork.c         # 编译到httpd服务器的MPM模块
  http_core.c
  mod_so.c          # 支持DSO动态模块加载  

三、prefork
  prefork的工作原理是:控制进程在最初建立“StartServers”个子进程后,为了满足MinSpareServers设置的需要创建一个进程,等待一秒钟,继续创建两个,再等待一秒钟,继续创建四个……如此按指数级增加创建的进程数,最多达到每秒32个,直到满足 MinSpareServers设置的值为止。这就是预派生(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

# prefork MPM
         # 判断是否有prefork.c这个模块,有就生效,否则无效
StartServers      8          # 服务初始化的工作进程数(work process)
MinSpareServers    5         # 保持的最少空闲进程数
MaxSpareServers     20       # 保持的最大空闲进程数
ServerLimit      256         # 保持的最大活动进程数,设定MaxClients的上限值
MaxClients       256         # 最大并发连接数
MaxRequestsPerChild  4000    # 每个子进程在生命周期能服务的最大请求数
      IfModule 指令,意为判断模块是否存在,如果存在那么参数则生效,反之如果不存在此模块,参数将不会生效。
  StartServer 8
     指定服务器启动是建立的子进程的数量,prefork 默认为5。为了满足MinSpareServers设置的需要创建一个进程, 等待一秒钟,继续创建两个,再等待一秒钟,继续创建四个……如此按指数级增加创建的进程数,最多达到每秒32个,直到满足 MinSpareServers设置的值为止。这就是预派生 (prefork)的由来。这种模式可以不必在请求到来时再产生新的进程,从而减小了系统开销以增加性能。
  MinSpareServers 5
       指定维持空闲子进程的最小数量,默认为5。假如当前空闲子进程数少于MinSpareServers,那么apache 将以每秒一个的速度产生新的子进程。此参数不要设置的太大。举个例子:MinSpareServers 限定为5个,当有4个请求来了之后, 8 - 4 还剩4个,那么为了维持5个MinSpareServers, 就必须再创建一个子进程。
  MaxSpareServers 20
        设置保持空闲进程的最大数量,默认为20。如果当前有超过MaxSpareServers数量的空闲子进程,那么父进程将杀死(kill)多余的子进程。此参数不要设置过大。如果该参数设置比MinSpareServers小,apache将会自动将其修改成"MinSpareServers+1”。如果站点负载较大,可考虑同时加大MinSpareServers和MaxSpareServers。
  MaxClients 256
         限定同一时间客户端最大接入的数量(单个进程并发线程数)。默认为256,任何超过MaxClients限制的请求都会进入等候队列,一旦一个链接被释放,队列中的请求将得到服务。MaxClients的值不能超过 ServerLimit, 如果要增大这个值,必须同时增加ServerLimit.理论上来说这个值越大,性能就越好。最重要的值是MaxClients允许足够多的工作进程,同时又不会导致服务器当机。
      可通过查看httpd进程数:# ps -ef | grep httpd | wc -l,选择高峰期,结合当时服务器资源使用情况,来设置MaxClients。
ServerLimit 256
   默认的MaxClient最大是256个进程,假如想设置更大的值,就需要加上ServerLimit这个数。 200000是ServerLimit这个参数的最大值。假如需要更大,则必须编译apache,此前都是无需重新编译apache。生效前提是,必须放在其他指令的前面。
   要调整ServerLimit的值,首先必须关闭httpd服务,调整后再重启httpd。

  MaxRequestsPerChild
         每个子进程在其生存期内允许伺服的最大请求数量(每一个子进程最多响应多少次请求)。默认为10000到达MaxRequestsPerChild的限制后,子进程将会结束。
         如果MaxRequestsPerChild 为0,子进程将永远不会结束。将MaxRequestsPerChild 设置成非零值有两个好处:

  • 可以防止(偶然的)内存泄漏无限进行,从而耗尽内存。
  • 给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量。
    对于KeepAlive链接,只有第一个请求会被计数。事实上,它改变了每个子进程限制最大链接数量的行为。
  

     MaxClients是这些指令中最为重要的一个,设定的是Apache可以同时处理的请求,是对Apache性能影响最大的参数。其缺省值 256 是远远不够的,如果请求总数已达到这个值(可通过 ps -ef|grep http|wc -l 来确认),那么后面的请求就要排队,直到某个已处理请求完毕。这就是系统资源还剩下很多而HTTP访问却很慢的主要原因。系统管理员可以根据硬件配置 和负载情况来动态调整这个值。理论上这个值越大,可以处理的请求就越多。
  

  我们看看httpd进程:

[root@localhost ~]# ps -ef | grep httpd
root     10692     1  0 20:17 ?        00:00:00 /usr/sbin/httpd    # master process
apache   10786 10692  0 21:39 ?        00:00:00 /usr/sbin/httpd
apache   10787 10692  0 21:39 ?        00:00:00 /usr/sbin/httpd
apache   10788 10692  0 21:39 ?        00:00:00 /usr/sbin/httpd
apache   10789 10692  0 21:39 ?        00:00:00 /usr/sbin/httpd
apache   10790 10692  0 21:39 ?        00:00:00 /usr/sbin/httpd
apache   10791 10692  0 21:39 ?        00:00:00 /usr/sbin/httpd
apache   10792 10692  0 21:39 ?        00:00:00 /usr/sbin/httpd
apache   10793 10692  0 21:39 ?        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/init.d/httpd 是 httpd 服务的启动脚本,此脚本的配置文件为: /etc/sysconfig/httpd, 那么我们可以编辑配置文件/etc/sysconfig/httpd:
# vi /etc/sysconfig/httd
# 把下面这一行的注释去掉
HTTPD=/usr/sbin/httpd.worker
# 切换模式必须重启服务
# service httpd restart  worker默认的配置:
如果有这个模块就启用
StartServers       4         # 初始化的子进程数
MaxClients        300        # 并发请求最大数
MinSpareThreads     25         # 最小空闲线程数total=所有进程的线程数加起来
MaxSpareThreads     75         # 最大空闲线程数 total
ThreadsPerChild     25         # 每个子进程可生成的线程数
MaxRequestsPerChild    0         # 每个子进程可服务的最大请求数,0表示不限制[root@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设置了所有子进程中的线程总数。如果现有子进程中的线程总数不能满足负载,控制进程将派生新的子进程。
  参数:
–StartServer:服务器启动时一次性建立的子进程数量
–MaxClients:设定apache同一时间处理的最大请求数量,这里是指最大线程数量,大小仍受ServerLimit限制且必须是ThreadsPerChild的倍数。
–MinSpareThreads:设置最少的空闲线程数
–MaxSpareServers:设置最大的空闲线程数,必须大于等于MinSpareThreads加上ThreadsPerChild的和(因为每个子进程拥有的线程数是固定的)
–ThreadsPerChild:每个子进程建立的常驻线程,之后不会再创建新的线程。大小受ThreadLimit限制。
–MaxRequestsPerChild:每个子进程最多处理的请求数量,同prefork的一样
–ServerLimit:服务器允许配置的进程数上限,和ThreadLimit共同限制MaxClients(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-638165-1-1.html 上篇帖子: ubuntu apache2下目录结构 下篇帖子: Apache HTTP Server 虚拟主机配置(三)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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