我使用768mb ram运行centos 5.5。我一直在日志中获得server reached MaxClients setting, consider raising the MaxClients setting
,而且apache运行速度非常慢。当我看到仙人掌图时,它显示服务器甚至没有使用所有资源..这是当前配置
<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>
使用top我看
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小时。繁忙时期是星期一星期一。所以我将等到下周才能看到配置更改的进一步结果。但它看起来像以前的改进,我只有最多10个线程可用。看着这个,你认为我可以做更多的改进吗?
free -m
total used free shared buffers cached
Mem: 768 619 148 0 0 49
-/+ buffers/cache: 570 197
Swap: 0 0 0
新测试
在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 /分布式缓存
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
答案 0 :(得分:36)
当您使用带有mod_php的Apache时,apache在prefork
模式下强制执行,而不是worker
。因为,即使知道php5支持多线程,也知道一些php5库在多线程环境中表现不佳(例如,你可以在一个线程上调用其他php线程上的语言环境进行语言环境调用)
所以,如果php没有像php-fpm一样以cgi方式运行,你可以在apache中使用mod_php,在prefork模式下使用apache。 在您的测试中,您只需评论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 forks不会很快发布以处理另一个请求,这肯定会增加。
在最后一张图片上看到红色峰值之前的少量绿色?如果您可以在1分钟而不是5分钟的基础上绘制图表,您会看到此绿色数量不足以在没有任何错误消息的情况下接收传入流量。
现在设置1024
MaxClients
。我猜这个配置修改后没有采用cacti图,因为通过这样的修改,当没有更多的进程可用时,apache将继续分叉新的子进程,限制为1024个繁忙的子进程。拿一个像每个孩子20MB RAM的东西(或者你可能在PHP中有一个很大的memory_limit并且允许64MB或256MB这些并且这些PHP请求真的使用更多的RAM),也许是数据库服务器......你的服务器现在正在放慢速度,因为你只有768MB的RAM。也许当apache试图启动前20个孩子时,你已经达到了可用的RAM限制。
因此。一种经典的处理方法是检查apache fork使用的内存量(在运行时生成一些顶级命令),然后找出你可以使用这个RAM量处理多少并行请求(这意味着并行apache children in prefork模式)。例如,让我们说它 12 。以这种方式将此数字放在apache mpm设置中:
<IfModule prefork.c>
StartServers 12
MinSpareServers 12
MaxSpareServers 12
MaxClients 12
MaxRequestsPerChild 300
</IfModule>
这意味着您不会在流量增加或减少时移动分叉数,因为您总是希望使用所有RAM并为流量峰值做好准备。 300
表示您在300次请求后回收每个分支,它优于0,这意味着您不会有潜在的内存泄漏问题。 MaxClients设置为12 25或50,超过12来处理 (删除了这个奇怪的sentende,我不记得为什么我这么说,如果有超过12个请求进入,下一个请求将被推入Backlog队列,但你应该将MaxClient设置为你的目标进程数)。 / p>
ListenBacklog
队列,这可以排队一些请求,你可能会占用更大的队列,但是你可能会得到一些超时
是的,这意味着您无法处理超过12个并行请求。
如果您想处理更多请求:
如果您的问题确实存在流量峰值,则可以使用缓存(如代理缓存服务器)提供解决方案。如果PHP中的问题是随机的慢,那么......它是一个应用程序问题,你是否从PHP对另一个站点进行了一些HTTP查询?例如?
最后,正如@Jan Vlcinsky所述,您可以尝试 nginx ,其中php仅可用作 php-fpm 。如果你不能购买RAM并且必须处理大量的流量,那么它肯定会进行测试。
更新:关于内部虚拟连接(如果您的问题是,但可能没有)。
检查this link和this previous answer。这是正常的,但如果您没有简单的虚拟主机,这些请求可能会占用您的主要应用程序,生成慢速http查询并阻止常规用户访问您的apache进程。它们是在优雅的重装或儿童管理下产生的。
如果你没有一个简单的基础&#34;它有效&#34;默认的Virtualhost通过一些重写来阻止对您的应用程序的请求:
RewriteCond %{HTTP_USER_AGENT} ^.*internal\ dummy\ connection.*$ [NC]
RewriteRule .* - [F,L]
<强>更新强>
只有一个Virtualhost不能保护您免受内部虚拟连接的攻击,这是最糟糕的,您现在可以确定这些连接是在您唯一的Virtualhost上进行的。因此,您应该通过使用重写规则来避免对应用程序产生副作用。
阅读你的cacti图形,似乎你的apache在工作模式下没有处于prefork模式的bug。在debian上运行httpd -l
或apache2 -l
,并检查您是否有worker.c或prefork.c。如果您处于工作模式,您可能会在应用程序中遇到一些PHP问题,但您应该检查工作程序设置,这是一个示例:
<IfModule worker.c>
StartServers 3
MaxClients 500
MinSpareThreads 75
MaxSpareThreads 250
ThreadsPerChild 25
MaxRequestsPerChild 300
</IfModule>
你启动3个进程,每个进程包含25个线程(默认情况下3 * 25 = 75个并行请求),只允许75个线程无效,只要使用一个线程,就会分叉新进程,再添加25个线程。当你有超过250个线程什么都不做(10个进程)时,一些进程被杀死。您必须使用内存调整这些设置。这里允许500个并行进程(25个线程的20个进程)。您的用法可能更多:
<IfModule worker.c>
StartServers 2
MaxClients 250
MinSpareThreads 50
MaxSpareThreads 150
ThreadsPerChild 25
MaxRequestsPerChild 300
</IfModule>
答案 1 :(得分:1)
这是一种可以解决您的问题的方法,如果没有帮助进行故障排除。
创建与当前的
将所有“正常”用户流量发送到原始虚拟服务器
将特殊或长时间运行的流量发送到新的虚拟服务器
特殊或长时间运行的流量可以是报告生成,维护操作或其他任何您不希望在&lt;&lt; 1秒内完成的事情。这可能发生在服务API上,而不仅仅是网页。
如果您的资源利用率很低,但仍然超过MaxClients,那么最有可能的答案是新连接的到达速度快于可以提供服务的速度。将任何慢速操作放在第二个虚拟服务器上将有助于证明是否是这种情况。使用Apache访问日志来量化效果。
答案 2 :(得分:0)
您是否考虑使用nginx(或其他基于事件的Web服务器)而不是apache?
nginx应允许更多数量的连接并消耗更少的资源(因为它是基于事件的,并且不会为每个连接创建单独的进程)。无论如何,您将需要一些进程,执行实际工作(如WSGI服务器等),如果它们与前端Web服务器保持在同一服务器上,您只需将性能问题转移到一个不同的位置。
最新的apache版本应允许类似的解决方案(以事件为基础配置它),但这不是我的专业领域。
答案 3 :(得分:-1)
我建议使用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