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

[经验分享] 合理设置apache的连接数及进程工作方式

[复制链接]

尚未签到

发表于 2018-11-25 08:59:16 | 显示全部楼层 |阅读模式
5  MinSpareServers                  5
  MaxSpareServers                  10
  MaxClients                      150
  MaxRequestsPerChild              0
  2.要加到多少
  连接数理论上当然是支持越大越好,但要在服务器的能力范围内,这跟服务器的CPU、内存、带宽等都有关系。
  查看当前的连接数可以用:
  ps aux | grep httpd | wc -l
  或:
  pgrep httpd|wc -l
  计算httpd占用内存的平均数:
  ps aux|grep -v grep|awk '/httpd/{sum+=$6;n++};END{printsum/n}'
  由于基本都是静态页面,CPU消耗很低,每进程占用内存也不算多,大约200K。服务器内存有2G,除去常规启动的服务大约需要500M(保守估计),还剩1.5G可用,那么理论上可以支持1.5*1024*1024*1024/200000= 8053.06368
  约8K个进程,支持2W人同时访问应该是没有问题的(能保证其中8K的人访问很快,其他的可能需要等待1、2秒才能连上,而一旦连上就会很流畅)控制最大连接数的MaxClients,因此可以尝试配置为:
  StartServers                      5
  MinSpareServers                  5
  MaxSpareServers                  10
  ServerLimit                    5500
  MaxClients                    5000
  MaxRequestsPerChild              100
  注意,MaxClients默认最大为250,若要超过这个值就要显式设置ServerLimit,且ServerLimit要放在MaxClients之前,值要不小于MaxClients,不然重启httpd时会有提示。
  重 启httpd后,通过反复执行pgrep httpd|wc -l来观察连接数,可以看到连接数在达到MaxClients的设值后不再增加,但此时访问网站也很流畅,那就不用贪心再设置更高的值了,不然以后如果网站访问突增不小心就会耗光服务器内存,可根据以后访问压力趋势及内存的占用变化再逐渐调整,直到找到一个最优的设置值。
  (MaxRequestsPerChild不能设置为0,可能会因内存泄露导致服务器崩溃)
  更佳最大值计算的公式:
  apache_max_process_with_good_perfermance   php.ini
  PHP 的配置是在 php.ini 中完成的。四个重要的设置控制 PHP 可使用多少系统资源,如表 1 所列。
  表 1. php.ini中与资源相关的设置设置    描述    建议值
  max_execution_time    一个脚本可使用多少CPU秒    30
  max_input_time    一个脚本等待输入数据的时间有多长(秒)    60
  memory_limit    在被取消之前,一个脚本可使用多少内存(字节)    32M
  output_buffering    数据发送给客户机之前,有多少数据(字节)需要缓存    4096
  具 体数字主要取决于您的应用程序。如果要从用户处接收大文件,那么 max_input_time 可能必须增加,可以在 php.ini中修改,也可以通过代码重写它。与之类似,CPU或内存占用较多的程序也可能需要更大的设置值。目标就是缓解超标程序的影响,因此不建议全局禁用这些设置。关于max_execution_time,还有一点需要注意:它表示进程的 CPU 时间,而不是绝对时间。因此一个进行大量 I/O和少量计算的程序的运行时间可能远远超过 max_execution_time。这也是 max_input_time 可以大于max_execution_time 的原因所在。
  PHP可执行的日志记录数是可配置的。在生产环境中,禁用除最重要的日志以外的一切日志记录能够减少磁盘写操作。如果需要使用日志来排除问题,那么可以按需启用日志记录。error_reporting = E_COMPILE_ERROR|E_ERROR|E_CORE_ERROR将启用足够的日志记录,使您发现问题,同时从脚本中消除大量无用的内容。
  apache的参数设置
  如何知道apache是工作在哪个模式下的,答案很简单:apachectl-l即可。这里,我先以prefork模式为例来说明参数的设置,其缺省设置一般如下:
  StartServers              5
  MinSpareServers            5
  MaxSpareServers          10
  MaxClients              150
  MaxRequestsPerChild        0
  prefork控制进程在最初建立“StartServers”个子进程后,为了满足MinSpareServers设置的需要创建一个进程,等待一秒钟,继续创建两个,再等待一秒钟,继续创建四个……如此按指数级增加创建的进程数,最多达到每秒32个,直到满足MinSpareServers设置的值为止。这种模式可以不必在请求到来时再产生新的进程,从而减小了系统开销以增加性能。MaxSpareServers设置了最大的空闲进程数,如果空闲进程数大于这个值,Apache会自动kill掉一些多余进程。这个值不要设得过大,但如果设的值比MinSpareServers小,Apache会自动把其调整为MinSpareServers+1。如果站点负载较大,可考虑同时加大MinSpareServers和MaxSpareServers。MaxRequestsPerChild设置的是每个子进程可处理的请求数。每个子进程在处理了“MaxRequestsPerChild”个请求后将自动销毁。0意味着无限,即子进程永不销毁。虽然缺省设为0可以使每个子进程处理更多的请求,但如果设成非零值也有两点重要的好处:1、可防止意外的内存泄漏。2、在服务器负载下降的时侯会自动减少子进程数。因此,可根据服务器的负载来调整这个值。MaxClients是这些指令中最为重要的一个,设定的是Apache可以同时处理的请求,是对Apache性能影响最大的参数。其缺省值150是远远不够的,如果请求总数已达到这个值(可通过ps-ef|grep httpd|wc-l来确认),那么后面的请求就要排队,直到某个已处理请求完毕。这就是系统资源还剩下很多而HTTP访问却很慢的主要原因。虽然理论上这个值越大,可以处理的请求就越多,但Apache默认的限制不能大于256。ServerLimit指令无须重编译Apache就可以加大MaxClients。
  注意,虽然通过设置ServerLimit,我们可以把MaxClients加得很大,但是往往会适得其反,系统耗光所有内存。以我手头的一台服务器为例:内存2G,每个apache进程消耗大约0.5%(可通过psaux来确认)的内存,也就是10M,这样,理论上这台服务器最多跑200个apache进程就会耗光系统所有内存,所以,设置MaxClients要慎重。
  再来看看work模式,缺省参数一般如下:
  StartServers              2
  MaxClients              150
  MinSpareThreads          25
  MaxSpareThreads          75
  ThreadsPerChild          25
  MaxRequestsPerChild        0
  Worker由主控制进程生成“StartServers”个子进程,每个子进程中包含固定的ThreadsPerChild线程数,各个线程独立地处理请求。同样,为了不在请求到来时再生成线程,MinSpareThreads和MaxSpareThreads设置了最少和最多的空闲线程数;而MaxClients设置了同时连入的clients最大总数。如果现有子进程中的线程总数不能满足负载,控制进程将派生新的子进程。MinSpareThreads和MaxSpareThreads的最大缺省值分别是75和250。这两个参数对Apache的性能影响并不大,可以按照实际情况相应调节。ThreadsPerChild是workerMPM中与性能相关最密切的指令。ThreadsPerChild的最大缺省值是64,如果负载较大,64也是不够的。这时要显式使用ThreadLimit指令,它的最大缺省值是20000。Worker模式下所能同时处理的请求总数是由子进程总数乘以ThreadsPerChild值决定的,应该大于等于MaxClients。如果负载很大,现有的子进程数不能满足时,控制进程会派生新的子进程。默认最大的子进程总数是16,加大时也需要显式声明ServerLimit(最大值是20000)。需要注意的是,如果显式声明了ServerLimit,那么它乘以ThreadsPerChild的值必须大于等于MaxClients,而且MaxClients必须是ThreadsPerChild的整数倍,否则Apache将会自动调节到一个相应值。
  ----------------------------------------
  对apache中并发控制参数prefork理解和调优
  一个apache有linux下的并发不是很高的,大约到3K的样子(其实处理的http的请求可能只有300/s),普通的服务器都会不同程度的出现问题.apache有关并发控制主要是 prefork和worker二个其中一个来控制.我们可以使用httpd-l来确定当前使用的MPM是prefork.c,还是Worker.c.下面是apache中有关prefork的配置.下面是我优化过的参数.
  #有这个参数就不必像apache1一样修改源码才能修改256客户数的限制,听讲要放到最前面才会生效,2000是这个参数的最大值
  ServerLimit 2000
  #指定服务器启动时建立的子进程数量,prefork默认为5。
  StartServers 25
  #指定空闲子进程的最小数量,默认为5。如果当前空闲子进程数少于MinSpareServers,那么Apache将以最大每秒一个的速度产生新的子进程。此参数不要设的太大。
  MinSpareServers 25
  #设置空闲子进程的最大数量,默认为10。如果当前有超过MaxSpareServers数量的空闲子进程,那么父进程将杀死多余的子进程。此参数不要设的太大。如果你将该指令的值设置为比MinSpareServers小,Apache将会自动将其修改成"MinSpareServers+1"。
  MaxSpareServers 50
  #限定同一时间客户端最大接入请求的数量(单个进程并发线程数),默认为256。任何超过MaxClients限制的请求都将进入等候队列,一旦一个链接被释放,队列中的请求将得到服务。要增大这个值,你必须同时增大ServerLimit。
  MaxClients 2000
  #每个子进程在其生存期内允许伺服的最大请求数量,默认为10000.到达MaxRequestsPerChild的限制后,子进程将会结束。如果MaxRequestsPerChild为"0",子进程将永远不会结束。
  MaxRequestsPerChild 10000
  将MaxRequestsPerChild设置成非零值有两个好处:
  1.可以防止(偶然的)内存泄漏无限进行,从而耗尽内存。
  2.给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量。
  工作方式:
  一 个单独的控制进程(父进程)负责产生子进程,这些子进程用于监听请求并作出应答。Apache总是试图保持一些备用的(spare)或者是空闲的子进程用于迎接即将到来的请求。这样客户端就不需要在得到服务前等候子进程的产生。在Unix系统中,父进程通常以root身份运行以便邦定80端口,而Apache产生的子进程通常以一个低特权的用户运行。User和Group指令用于设置子进程的低特权用户。运行子进程的用户必须要对它所服务的内容有读取的权限,但是对服务内容之外的其他资源必须拥有尽可能少的权限。
  对上面的有些值,一定要记的不是越大越好.这个需要经过几次尝试和出错之后才能选好要使用的值(不同的硬件处理水平不一样)。最重要的值是maxclient允许足够多的工作进程,同时又不会导致服务器进行过度的交换(死机)。如果传入的请求超出处理能力而让服务器当掉的话,那么至少满足此值的那些请求会得到服务,其他请求被阻塞这样会更加好。
  我们调优常常要查看httpd进程数(即prefork模式下Apache能够处理的并发请求数):
  #ps -ef | grep httpd | wc -l
  出现的结果,就是当前Apache能够处理的多少个并发请求,这个值Apache根据负载情况自动调.
  查看Apache的并发请求数及其TCP连接状态:
  #netstat -n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a,S[a]}’
  返回结果示例:
  LAST_ACK 5
  SYN_RECV 38
  ESTABLISHED 1600
  FIN_WAIT1 51
  FIN_WAIT2 515
  TIME_WAIT 1857
  其中的SYN_RECV表示正在等待处理的请求数;ESTABLISHED表示正常数据传输状态;TIME_WAIT表示处理完毕,等待超时结束的请求数。
  状态:描述
  CLOSED:无连接是活动的或正在进行
  LISTEN:服务器在等待进入呼叫
  SYN_RECV:一个连接请求已经到达,等待确认
  SYN_SENT:应用已经开始,打开一个连接
  ESTABLISHED:正常数据传输状态
  FIN_WAIT1:应用说它已经完成
  FIN_WAIT2:另一边已同意释放
  ITMED_WAIT:等待所有分组死掉
  CLOSING:两边同时尝试关闭
  TIME_WAIT:另一边已初始化一个释放
  LAST_ACK:等待所有分组死掉
  可以使用Linux下的webbench来作压力测试.
  apache 的 MaxRequestsPerChild指令设置不合理导致并发连接过高会导致服务器负荷增大,尝试优化和调整服务器,首先是从 Apache 的优化和调整开始的。
  从网络上搜索到一篇文章,说加大 MaxRequestsPerChild可以促使增加子进程的复用,从而提高效率。不记得那篇文章是否提到了其使用的 Apache 的 MPM ,版本是 2.0 的没错,反正不是woker 就是 prefork 了。
  我使用的 prefork ,参考那篇文章,将 MaxRequestsPerChild 由 300 调整到了 3000 。
  结果,后两天的监控结果是,在网站访问期的高峰期,服务器负荷很重,数据库的并发连接频频超过最高限制。Apache的并发连接也几乎一直保持在最高,网站访问速度很慢,频繁出现访问超时的问题。
  最开始以为是网站访问量过大,达到服务器硬件极限导致的正常现象,不过,手动重启 Apache后,数据库并发连接迅速降低,之后缓慢增加,一直达到最高并发连接限制,并且很长时间无法减小。
  之后,认为是数据库并发连接过高,导致系统负荷过大,而 Apache 过多的 KeepAlice连接导致数据库的并发连接无法及时释放从而消耗大量系统资源,导致系统负荷过重。最后,怀疑到 MaxRequestsPerChild 的300 设置是否合理。

  阅 读 Apache 手册关于 MaxRequestsPerChild 的说明后,认为 prefork 下,KeepAlice开启的情况下,每一个新连接都会导致一个 Apache 子进程开启, MaxRequestsPerChild设置过大,导致新连接产生新的子进程后,长期>  根据网站的访问情况,并不需要那么大的 MaxRequestsPerChild ,客户端和 Apache 采用 http进行连接,网站都是一些大小不大的文件,客户端在和 Apache服务器数次交互后,就应该完成一次访问了,用户点击网站的频率也不会那么高,所以 MaxRequestsPerChild不应该设置那么高,而应该设置低一些,以尽快释放数据库连接,尽快回收系统资源,以尽可能快速的满足新的请求的连接需求。将MaxRequestsPerChild 重新调整回默认的 300 ,情况有所改观。
  最后,就像那句古话所说的,尽信书不如无书,换到互联网上也一样。不能盲目的参考网上的资料,特别是非严格发表的个人经验文档。网上的资料始终都只能作为参考,必须要经过自己的理解,再结合实际情况,进行调整。不然,导致的结果可能是无法预计的。
  MaxRequestsPerChild 这个指令设定一个独立的子进程将能处理的请求数量。在处理“MaxRequestsPerChild数字”个请求之后,子进程将会被父进程终止,这时候子进程占用的内存就会释放,如果再有访问请求,父进程会重新产生子进程进行处理。如果MaxRequestsPerChild缺省设为0(无限)或较大的数字(例如10000以上)可以使每个子进程处理更多的请求,不会因为不断终止、启动子进程降低访问效率,但MaxRequestsPerChild设置为0时,如果占用了200~300M内存,即使负载下来时占用的内存也不会减少。内存较大的服务器可以设置为0或较大的数字。内存较小的服务器不妨设置成30、50、100,以防内存溢出。
  如何避免apache的httpd进程占用比较多的内存
  目前apache的主流工作模式MPM模式。MPM是Multi-Processing-Modules的简称,意思是多道处理模块。MPM模块有不同的种类。现在用的比较多的MPM种类主要是prefork和worker。prefork的工作方式是多个进程工作,每个进程会在处理一定数量的请求后结束(这个数量可能是无穷),没有线程的概念。worker被看作apache未来的主流工作模式,它是一种多进程与多线程混合的模式。
  最近发现一个比较奇怪的现象,某台以prefork模式工作的服务器的内存使用率在每次重启apache之后会不停的上涨,直到swap用完,直到死机。后来查出来是因为apache使用的某一些脚本存在内存泄露的代码段。而apache启动的调用这些代码段的进程的处理请求数被设置为无穷。也就是说这些进程只有在apache重启(stop-start模式)或者服务器(指的是机器)重启的情况下才会被kill,否则将一直运行下去,直到耗尽系统的最后一点资源(主要是内存)。
  问题貌似已经解决了。但是,还有点不对,就是为什么有将近4G的可用空间(内存2G加上swap2G,除去操作系统部分),资源还是很快就耗尽了?虽然进程在每处理一个请求的情况下都会吃掉一点内存,但是在看了内存泄露的那段代码后发现每次处理泄露的内存也不过2K左右。要消耗掉3G的空间,需要至少15.7w次请求。但是目前的手机统计平台上一天的点击量也不过5w。其实top命令下就能看出来,每个httpd进程的内存使用率有2.4%,3.2%等等。对于一个2G内存的服务器,一个进程2%就等于是40M。仅仅一个普通的请求,没有post参数的,没有大规模数据库查询的,怎么会用这么多内存?httpd的进程在被apache的主控进程创建的时候,会预先加载一些包,这些包是在apache配置文件里设置的。然后发现在apache加载的包目录下,有一个很大的包,是用来根据手机号查找手机卡的信息的。去掉这个包之后,每个httpd的进程使用内存就正常了。
  总结有两点:
  1、MaxRequestsPerChild不能设置为0,最好设置为一个相对不大的数字,防止httpd进程有意外的内存泄露(当然,也不建议设置为1,否则apache就会不停的fork新的进程了,cpu的资源也就过多消耗了);
  2、不要加载过多的包,尤其是比较大的包。如果费用不可,最好能够用数据库来存储包里的一些静态信息。
  Apache连接数的设置方法
  prefork几乎还是目前的唯一MPM,我在下面主要还是讨论它的工作原理和相关指令调整。查看缺省生成的httpd.conf配置文件,会发现里面包含如下的配置段:
  以下为引用的内容:
  StartServers 5
  MinSpareServers 5
  MaxSpareServers 10
  MaxClients 150
  MaxRequestsPerChild 0
  prefork 的工作原理是这样的:控制进程在最初建立StartServers个子进程后,为了满足MinSpareServers设置的需要,创建一个进程,等待一秒钟,继续创建第二个,等待一秒钟,继而创建四个,如此按指数级增加创建的进程数,最多达到每秒32个,直到满足MinSpareServers设置的值为止,这也就是预派生(prefork)的由来。这种模式可以使得不必在请求到来时再产生新的进程,从而减小了系统开销以增加性能。
  axSpareServers设置了最大的空闲进程数,如果空闲进程数大于这个值,apache(Unix平台最流行的WEB服务器平台)会自动kill某些多余进程。这个值一般不要设的过大,但如果设的比MinSpareServers小,apache(Unix平台最流行的WEB服务器平台)会自动把它调整为MinSpareServers+1。如果站点负载较大的话,可考虑同时加大MinSpareServers和MaxSpareServers。
  MaxRequestsPerChild设置的是每个子进程可以处理的请求数。每个子进程在处理了MaxRequestsPerChild个请求后将自动销毁。0意味着无限,即子进程永不销毁。虽然缺省设为0可以使每个子进程处理更多的请求,但如果设成非零值也有两点重要的好处:
  1、可防止意外的内存卸漏;
  2、在服务器负载下降的时侯会自动减少子进程数。
  因此,可根据服务器的负载来调整这个值,如果非零的话,笔者认为10000左右是比较合适的。事实上这个值对apache(Unix平台最流行的WEB服务器平台)的性能影响不是很大。
  MaxClients是这些指令中最为重要的一个,它设定的就是apache(Unix平台最流行的WEB服务器平台)可以同时处理的请求,这是对apache(Unix平台最流行的WEB服务器平台)性能影响最大的参数.在我个人看来,缺省的150是远远不够的,如果请求总数已达到这个值(可通过ps–ef|grep httpd|wc–l来确认),那么下面的请求就要排队,直到某个已处理请求完毕。这就是为什么系统资源还剩下很多,而http访问却很慢的主要原因。系统管理员可以根据硬件配置和负载情况来动态调整这个值,虽然理论上这个值越大,可以处理的请求就越多,但apache(Unix平台最流行的WEB服务器平台)默认的限制是不能大于256。如果把这个值设为大于256那么apache(Unix平台最流行的WEB服务器平台)将无法起动。事实上,256对于负载稍重的站点也是很不够的。在apache(Unix平台最流行的WEB服务器平台)1.3中这是个硬限制,如果要加大这个值,必须在configure前手工修改源代码树下的src/include/httpd.h,查找256,会发现#define HARD_SERVER_LIMIT256这行,把256改为你要增大的值如4000,然后重新编译apache(Unix平台最流行的WEB服务器平台)即可。我想这个方法稍有些经验的apache(Unix平台最流行的WEB服务器平台)系统管理员都知道,不过我相信在apache(Unix平台最流行的WEB服务器平台)2.0中知道如何加大这个值的人就不会太多了。
  在apache(Unix平台最流行的WEB服务器平台)2.0中新加入了ServerLimit指令,使得无须重编译apache(Unix平台最流行的WEB服务器平台)就可以加大MaxClients。下面是笔者的prefork配置段。
  以下为引用的内容:
  StartServers 10
  MinSpareServers 10
  MaxSpareServers 15
  ServerLimit 2000
  MaxClients 1500
  MaxRequestsPerChild 10000
  BTW:ServerLimit的最大值是20000,这对于大多数站点是足够了,但如果你一定要再加大的话,那么这个值位于源代码树下的server/mpm/prefork/prefork.c中。里面的
  #define DEFAULT_SERVER_LIMIT 256
  #define MAX_SERVER_LIMIT 20000
  这两行就对应着MaxClients和ServerLimit的限制值。但我相信很少有人可以用到20000的并发连接数。


运维网声明 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-639250-1-1.html 上篇帖子: Apache MINA (3) NioSocketAcceptor初始化 下篇帖子: linux笔记—
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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