Apache服务器达到MaxClients设置,考虑提高MaxClients设置

我正在运行centos 5.5,内存为768mb。 我不断得到server reached MaxClients setting, consider raising the MaxClients setting日志中server reached MaxClients setting, consider raising the MaxClients setting也阿帕奇运行真的很慢。 当我看着仙人掌图,它显示服务器甚至没有使用所有的资源..这里是当前的configuration

 <IfModule prefork.c> StartServers 8 MinSpareServers 5 MaxSpareServers 10 ServerLimit 1024 MaxClients 768 MaxRequestsPerChild 4000 </IfModule> <IfModule worker.c> StartServers 2 MaxClients 150 MinSpareThreads 25 MaxSpareThreads 75 ThreadsPerChild 25 MaxRequestsPerChild 0 </IfModule> free -m total used free shared buffers cached Mem: 768 352 415 0 0 37 -/+ buffers/cache: 315 452 Swap: 0 0 0 top - 11:03:54 up 41 days, 11:53, 1 user, load average: 0.05, 0.03, 0.00 Tasks: 35 total, 1 running, 34 sleeping, 0 stopped, 0 zombie Cpu(s): 0.0%us, 0.0%sy, 0.0%ni, 99.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.3%st Mem: 786432k total, 389744k used, 396688k free, 0k buffers Swap: 0k total, 0k used, 0k free, 38284k cached 

我已经尝试了以下,但服务器响应非常缓慢

 <IfModule worker.c> #StartServers 2 #MaxClients 150 #MinSpareThreads 25 #MaxSpareThreads 75 #ThreadsPerChild 25 #MaxRequestsPerChild 0 StartServers 20 MaxClients 1024 ServerLimit 1024 MinSpareThreads 128 MaxSpareThreads 768 ThreadsPerChild 64 MaxRequestsPerChild 0 </IfModule> free -m total used free shared buffers cached Mem: 768 324 443 0 0 37 -/+ buffers/cache: 286 481 Swap: 0 0 0 

在这里输入图像说明

@regilero

我已经更新到

 <IfModule prefork.c> StartServers 12 MinSpareServers 12 MaxSpareServers 12 MaxClients 50 MaxRequestsPerChild 300 </IfModule> 

使用顶部,我看到

 Tasks: 36 total, 1 running, 35 sleeping, 0 stopped, 0 zombie Cpu(s): 0.0%us, 0.3%sy, 0.0%ni, 99.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 786432k total, 613180k used, 173252k free, 0k buffers Swap: 0k total, 0k used, 0k free, 76488k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 20 0 10364 92 60 S 0.0 0.0 1:09.53 init 2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd/808 3 root 20 0 0 0 0 S 0.0 0.0 0:00.00 khelper/808 124 root 16 -4 12620 8 4 S 0.0 0.0 0:00.00 udevd 533 root 20 0 95504 5692 228 S 0.0 0.7 4:02.94 memcached 546 root 20 0 5924 332 276 S 0.0 0.0 6:54.51 syslogd 557 root 20 0 101m 1456 868 S 0.0 0.2 13:18.64 snmpd 570 root 20 0 62640 316 208 S 0.0 0.0 2:39.56 sshd 579 root 20 0 21656 24 20 S 0.0 0.0 0:00.00 xinetd 589 root 20 0 12072 12 8 S 0.0 0.0 0:00.05 mysqld_safe 940 mysql 20 0 559m 164m 3832 S 0.3 21.5 209:33.88 mysqld 1015 root 20 0 20880 200 132 S 0.0 0.0 0:10.48 crond 1023 root 20 0 46748 4 0 S 0.0 0.0 0:00.00 saslauthd 1024 root 20 0 46748 4 0 S 0.0 0.0 0:00.00 saslauthd 3605 root 20 0 62832 2168 636 S 0.0 0.3 0:02.58 sendmail 3613 smmsp 20 0 57712 1648 504 S 0.0 0.2 0:00.01 sendmail 17610 root 20 0 85932 3312 2600 S 0.0 0.4 0:00.02 sshd 17612 mcmap 20 0 86072 1760 1012 S 0.0 0.2 0:00.17 sshd 17613 mcmap 20 0 12076 1656 1292 S 0.0 0.2 0:00.01 bash 17637 root 20 0 45052 1432 1120 S 0.0 0.2 0:00.00 su 17638 root 20 0 12180 1800 1324 S 0.0 0.2 0:00.08 bash 17740 root 20 0 246m 9264 4516 S 0.0 1.2 0:00.19 httpd 18264 apache 20 0 282m 43m 4940 S 0.0 5.7 0:00.56 httpd 18514 apache 20 0 279m 40m 4832 S 0.0 5.3 0:01.47 httpd 18518 apache 20 0 273m 36m 4396 S 0.0 4.7 0:00.45 httpd 18528 apache 20 0 251m 13m 3660 S 0.0 1.8 0:00.41 httpd 18529 apache 20 0 278m 40m 4340 S 0.0 5.3 0:00.99 httpd 18530 apache 20 0 278m 40m 4268 S 0.0 5.3 0:00.67 httpd 18548 apache 20 0 272m 33m 3516 S 0.0 4.4 0:00.28 httpd 18552 apache 20 0 280m 42m 3684 S 0.0 5.5 0:00.48 httpd 18553 apache 20 0 271m 33m 3768 S 0.0 4.3 0:00.45 httpd 18555 apache 20 0 274m 36m 3672 S 0.0 4.7 0:00.58 httpd 18572 apache 20 0 247m 9020 2856 S 0.0 1.1 0:00.01 httpd 18578 apache 20 0 280m 42m 3684 S 0.0 5.6 0:00.76 httpd 18589 apache 20 0 246m 5452 676 S 0.0 0.7 0:00.00 httpd 18588 root 20 0 12624 1216 932 R 0.0 0.2 0:00.06 free -m total used free shared buffers cached Mem: 768 578 189 0 0 74 -/+ buffers/cache: 504 263 Swap: 0 0 0 

在这里输入图像说明 刚刚添加了最近4个小时的仙人掌结果的图片。 繁忙的时期是星期一的星期一。 所以我会等到下个星期才能看到configuration更改的更多结果。 但看起来像以前一样,我只有最多10个线程可用。 看着这个,你觉得我可以做更多的改进吗?

 free -m total used free shared buffers cached Mem: 768 619 148 0 0 49 -/+ buffers/cache: 570 197 Swap: 0 0 0 

新的testing

在一个2GB的Ram VPS盒子上,我现在已经设置了prefork

 StartServers 20 MinSpareServers 20 MaxSpareServers 20 ServerLimit 256 MaxClients 256 MaxRequestsPerChild 4000 

今天早上我的memcache服务器死亡

 Nov 20 09:28:40 vps22899094 kernel: Out of memory: Kill process 12517 (memcached) score 81 or sacrifice child Nov 20 09:28:40 vps22899094 kernel: Killed process 12517, UID 497, (memcached) total-vm:565252kB, anon-rss:42940kB, file-rss:44kB 

在apache中应该设置哪些最佳值?

#在/ etc / SYSCONFIG / memcached的

 PORT="11211" USER="memcached" MAXCONN="1024" CACHESIZE="1024" OPTIONS="-l 127.0.0.1" 

/etc/my.cnf中

 [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 bind-address=127.0.0.1 #script thread_concurrency=2 query_cache_size = 16M query_cache_type=1 query_cache_limit=5M # MyISAM # #key-buffer-size = 32M #myisam-recover = FORCE,BACKUP # SAFETY # #max-allowed-packet = 16M #max-connect-errors = 1000000 # CACHES AND LIMITS # tmp-table-size = 32M max-heap-table-size = 32M #query-cache-type = 0 #query-cache-size = 0 max-connections = 50 thread-cache-size = 16 #open-files-limit = 65535 #table-definition-cache = 1024 #table-open-cache = 2048 # INNODB # #innodb-flush-method = O_DIRECT #innodb-log-files-in-group = 2 #innodb-log-file-size = 5M #innodb-flush-log-at-trx-commit = 1 #innodb-file-per-table = 1 #innodb-buffer-pool-size = 921M # LOGGING # log-error = /var/log/mysqld.log log-queries-not-using-indexes = 1 slow-query-log = 1 slow-query-log-file = /var/log/mysqld-slow.log [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid 

    当你用mod_php使用Apache时,apache在prefork模式下执行,而不是worker 。 因为,即使已知php5支持多线程,也知道一些php5库在多线程环境中表现不佳(例如,您将在一个线程上改变语言环境调用,例如在其他php线程上改变语言环境) 。

    所以,如果php不是像php-fpm那样以cgi的方式运行的话,那么你的mod_php在apache和apache里就是prefork模式。 在你的测试中,你只是简单地评论了prefork设置,并增加了工作者设置,你现在拥有的是prefork设置的默认值和一些共享值的修改值:

     Startservers 20 MinSpareservers 5 MaxSpareservers 10 MaxClients 1024 MaxRequestsPerChild 0 

    这意味着你要求apache从20进程开始,但是你告诉它,如果有超过10个进程什么都不做,那么应该减少这个数量的子进程,保持5到10个进程可用。 apache的增加/减少速度是每分钟1。 所以很快你就会回到传统的情况下,你有一个相当少的免费可用的Apache进程(平均2)。 平均数低,因为通常你有5个可用的进程,但只要流量增长,他们都被使用,所以没有可用的进程,因为Apache创建新的分支非常缓慢。 这肯定是因为你的PHP请求似乎很长,他们没有提前完成,而且Apache的叉子没有及时发布到足以处理另一个请求。

    在最后的图形上看到红色峰值之前的少量绿色? 如果您可以在1分钟而不是5分钟的基础上绘制这个图表,那么您会看到,这个绿色金额并不足以在没有任何错误消息的情况下接收到传入的流量。

    现在你设置了1024 MaxClients 。 我猜这个配置修改后并没有采用仙人掌图,因为经过这样的修改,当没有更多的进程可用时,apache将继续分叉新的子进程,限制为1024个繁忙的子进程。 采取像每个孩子20MB的内存(或者也许你有一个大的memory_limit在PHP中,并允许像64MB或256MB这些PHP请求实际上使用更多的内存),也许是一个数据库服务器…您的服务器现在放缓,因为你只有768MB的RAM。 也许当Apache试图启动前20个孩子,你已经达到了可用的内存限制。

    所以。 一个经典的处理方法是检查一个apache fork的内存量(在运行的时候创建一些top命令),然后找出你可以处理多少个并行请求(这意味着并行的apache子进程prefork模式)。 比方说,这是12 。 把这个数字放在apm的mpm设置中:

     <Ifmodulee prefork.c> Startservers 12 MinSpareservers 12 MaxSpareservers 12 MaxClients 12 MaxRequestsPerChild 300 </Ifmodulee> 

    这意味着当流量增加或减少时,您不会移动叉的数量,因为您总是要使用所有的RAM并为流量峰值做好准备。 300意味着你在300次请求后回收每个分支,它比0好,这意味着你不会有潜在的内存泄漏问题。 MaxClients被设置为12个25或50个,超过12个来处理listnBacklog队列,这个队列可以排队一些请求,你可以占用一个更大的队列,但是你可能会得到一些超时可能会删除这个奇怪的句子,我不记得了为什么我这么说,如果有超过12个请求被传入,下一个请求将被压入Backlog队列,但是你应该把MaxClient设置为你的目标进程数)。

    是的,这意味着你不能处理超过12个并行请求。

    如果你想处理更多的请求:

    • 买更多的内存
    • 尝试在工作模式下使用Apache,但删除mod_php并使用PHP作为与他自己的池设置(这称为php-fpm )并行守护进程,将其与fastcgi连接。 请注意,你一定需要购买一些内存,以允许大量的并行php-fpm进程,但可能会少于mod_php
    • 减少在你的PHP过程中花费的时间 。 从你的仙人掌图你有潜在的问题:11:25-11:30左右的真正流量峰值或一些PHP代码变得非常缓慢。 快速请求将减少并行请求的数量。

    如果您的问题确实是流量高峰,那么解决方案可以用于缓存,如代理缓存服务器。 如果这个问题在PHP中是一个随机缓慢的话,那么这是一个应用程序问题,例如,您是否会对PHP的另一个站点执行一些HTTP查询?

    最后,如@Jan Vlcinsky所述,您可以尝试nginx ,其中php只能以php-fpm的形式提供 。 如果你不能购买内存,并且必须处理大量的流量,这绝对是一个测试。

    更新:关于内部虚拟连接 (如果这是你的问题,但也许不是)。

    检查这个链接和这个以前的答案 。 这是'正常的',但如果你没有一个简单的虚拟主机这些请求可能会击中你的主要沉重的应用程序,生成缓慢的http查询,并阻止普通用户访问您的Apache进程。 它们是在优雅的重新装载或儿童管理上产生的。

    如果你没有一个简单的基本“它的工作原理”默认虚拟主机防止这些请求在你的应用程序的一些重写:

      RewriteCond %{HTTP_USER_AGENT} ^.*internal\ dummy\ connection.*$ [NC] RewriteRule .* - [F,L] 

    更新:

    只有一个虚拟主机不能保护你不受内部虚拟连接的影响,这是最糟糕的,你现在肯定这些连接是在你独特的虚拟主机上进行的。 所以你应该通过使用重写规则来真正避免应用程序的副作用。

    读取你的仙人掌图形,似乎你的Apache不在工作模式prefork模式错误。 在debian上运行httpd -lapache2 -l ,检查是否有worker.c或prefork.c。 如果您处于工作模式,您可能会在应用程序中遇到一些PHP问题,但您应该检查工作人员设置,这里是一个示例:

     <Ifmodulee worker.c> Startservers 3 MaxClients 500 MinSpareThreads 75 MaxSpareThreads 250 ThreadsPerChild 25 MaxRequestsPerChild 300 </Ifmodulee> 

    你启动3个进程,每个进程包含25个线程(因此3 * 25 = 75个并行请求默认情况下可用),只要一个线程被使用,一个新的进程被分叉,再增加25个线程,就允许75个线程无所事事。 而当你有超过250个线程什么也不做(10个进程)时,一些进程被终止。 你必须用你的记忆来调整这些设置。 在这里,你允许500个并行进程(即25个进程的25个线程)。 你的用法也许更多:

     <Ifmodulee worker.c> Startservers 2 MaxClients 250 MinSpareThreads 50 MaxSpareThreads 150 ThreadsPerChild 25 MaxRequestsPerChild 300 </Ifmodulee> 

    这是一种可以解决您的问题的方法,如果不能解决您的问题。

    1. 创建第二个与当前服务器相同的Apache虚拟服务器

    2. 将所有“普通”用户流量发送到原始虚拟服务器

    3. 发送特殊或长时间运行的流量到新的虚拟服务器

    特殊的或长时间运行的交通可能是报告生成,维护操作或其他你不期望在1秒内完成的任何事情。 这可能发生服务的API,而不仅仅是网页。

    如果您的资源利用率较低,但仍然超过MaxClients,则最有可能的答案是您的新连接到达速度超过了可以服务的范围。 在第二台虚拟服务器上放置任何缓慢的操作将有助于证明情况是否如此。 使用Apache访问日志来量化效果。

    你有没有考虑使用nginx(或其他基于事件的Web服务器),而不是Apache?

    nginx应允许更多的连接,并消耗更少的资源(因为它是基于事件的,不会为每个连接创建单独的进程)。 无论如何,你将需要一些进程,做真正的工作(如WSGI服务器等),如果他们留在与前端Web服务器相同的服务器上,只会将性能问题转移到一个不同的地方。

    最新的apache版本应该允许类似的解决方案(以基于事件的方式进行配置),但这不是我的专业领域。

    我建议使用在Apache上建议的波纹管公式:

    MaxClients =(总RAM – OS的RAM – 外部程序的RAM)/(每个httpd进程的RAM)

    找到我的脚本在Rhel 6.7上运行。 您可以根据您的操作系统进行更改。

     #!/bin/bash echo "HostName=`hostname`" #Formula #MaxClients . (RAM - size_all_other_processes)/(size_apache_process) total_httpd_processes_size=`ps -ylC httpd --sort:rss | awk '{ sum += $9 } END { print sum }'` #echo "total_httpd_processes_size=$total_httpd_processes_size" total_http_processes_count=`ps -ylC httpd --sort:rss | wc -l` echo "total_http_processes_count=$total_http_processes_count" AVG_httpd_process_size=$(expr $total_httpd_processes_size / $total_http_processes_count) echo "AVG_httpd_process_size=$AVG_httpd_process_size" total_httpd_process_size_MB=$(expr $AVG_httpd_process_size / 1024) echo "total_httpd_process_size_MB=$total_httpd_process_size_MB" total_pttpd_used_size=$(expr $total_httpd_processes_size / 1024) echo "total_pttpd_used_size=$total_pttpd_used_size" total_RAM_size=`free -m |grep Mem |awk '{print $2}'` echo "total_RAM_size=$total_RAM_size" total_used_size=`free -m |grep Mem |awk '{print $3}'` echo "total_used_size=$total_used_size" size_all_other_processes=$(expr $total_used_size - $total_pttpd_used_size) echo "size_all_other_processes=$size_all_other_processes" remaining_memory=$(($total_RAM_size - $size_all_other_processes)) echo "remaining_memory=$remaining_memory" MaxClients=$((($total_RAM_size - $size_all_other_processes) / $total_httpd_process_size_MB)) echo "MaxClients=$MaxClients" exit