Apache 调优脚本(自动计算最大客户端数)
自动计算 Apache 的 MaxClients 配置值。
MySQLTuner 是一个著名的脚本,用于支持 MySQL 的调优。与此类似,在类似的思路下,还有一个脚本可以自动计算 Apache 的 MaxClients(Apache 2.4 以后为 MaxRequestWorkers)的设置值。
请参阅《Apache MaxClients的适当值》中对MaxClients最佳值的讨论。
国产品
海外制造的Apache2 Buddy可能是最接近的选项,但似乎只进行了简单计算,没有考虑子进程的共享内存等。结果是MaxClients的值较小,因此如果希望安全设置,则可以使用它。虽然我认为Remaining Memory的计算只涉及特定服务的除法运算,但分母的内存量可能较大,导致结果变得很大,所以请注意。
Your server's physical RAM: 993 MB
Remaining Memory after other services considered: 993 MB
Apache's MaxClients directive: 256 <--------- Current Setting
Apache MPM Model: prefork
[ !! ] Your MaxRequestWorkers setting is too high.
Your recommended MaxRequestWorkers setting is between 168 and 187. <------- Acceptable Range (10% of MAX)
Max potential memory usage: 1354 MB
Percentage of TOTAL RAM allocated to Apache: 136.38 %
Percentage of REMAINING RAM allocated to Apache: 136.38 %
子进程的内存输出
在子进程的内存输出中,none_shared_memory_fetcher.pl是根据伊藤直也先生的文章中著名的shared_memory_size.pl的流程来计算子进程的非共享内存的,但是MaxClients的值需要自行计算。
PID RSS SHARED NONE_SHARED
12538 3780 3072 (81%) 708
12540 3048 2836 (93%) 212
12541 3060 2840 (92%) 220
12542 3152 2908 (92%) 244
12543 3060 2840 (92%) 220
自动计算
如果您想尽力攻关,您可以使用 get_max_clients.sh 来自动计算考虑了子进程共享内存的 MaxClients 数值。尽管它并不完美,但这可能是一个不错的选择。
Memory Total / (Rss Average - Shr Average) = 1020076 / (3626 - 3263)
Memory Free / (Rss Average - Shr Average) = 635560 / (3626 - 3263)
MaxClients = 1750 ~ 2810
出的產品
Apachetuner.sh 的中文翻译:Apachetuner.sh
Gustav Maskowitz(@gusmaskowitz)的概念记录作为一个Shell脚本。已被他后来提到的Apachebuddy.pl替代。
curl -sL https://raw.githubusercontent.com/gusmaskowitz/apachetuner/master/apachetuner.sh | sh
=========================SYSTEM=========================
CentOS release 6.8 (Final)
Server Name: localhost.localdomain
Total Physical Memory: 996 MB
=========================APACHE=========================
Version: Apache/2.2.15 (Unix)
RPM: httpd-2.2.15-53.el6.centos.x86_64
httpd binary: /usr/sbin/httpd
Whats running on port 80 12538/httpd
Apache Architecture: 64-bit
Serverlimit is: 256
MaxClients is: 256
httpd root /etc/httpd
httpd server config file /etc/httpd/conf/httpd.conf
httpd default errorlog /etc/httpd/logs/error_log
=========================PHP============================
/etc/php.ini memory_limit is: 128M
=====================APACHE RUNTIME=====================
Apache user: apache
Average Memory use: 2.07 MB per child
Number of children: 8
=========================REPORT==========================
Current memory footprint 16.56 MB
Maximum memory footprint 529.92 MB (53% of installed RAM)
System memory divided by MaxClients 4
System memory divided by Apache child size 481
阿帕奇小伙伴
Apache Buddy是由Gustav Maskowitz(gusmaskowitz)创建的,作为apachetuner.sh的替代品,但由于ohaio-solo已经实施了相同的功能,因此它不再进行积极的开发。
curl -sL apachebuddy.pl | perl
########################################################################
# Apache Buddy v 0.3 ###################################################
########################################################################
Gathering information...
We are checking the service running on port 80
The process listening on port 80 is /usr/sbin/httpd
The process running on port 80 is Apache/2.2.15 (Unix)
Apache has been running 0d 0h 18m 39s
The full path to the Apache config file is: /etc/httpd/conf/httpd.conf
Apache is using prefork model
Examining your Apache configuration...
Apache runs as apache
Your max clients setting is 256
Analyzing memory use...
Your server has 996 MB of memory
The largest apache process is using 2.08 MB of memory
The smallest apache process is using 2.08 MB of memory
The average apache process is using 2.08 MB of memory
Going by the average Apache process, Apache can potentially use 532.49 MB RAM (53.47 % of available RAM)
Going by the largest Apache process, Apache can potentially use 532.49 MB RAM (53.47 % of available RAM)
Generating reports...
### GENERAL REPORT ###
Settings considered for this report:
Your server's physical RAM: 996MB
Apache's MaxClients directive: 256
Apache MPM Model: prefork
Largest Apache process (by memory): 2.08MB
[ OK ] Your MaxClients setting is within an acceptable range.
Max potential memory usage: 532.48 MB
Percentage of RAM allocated to Apache 53.47 %
-----------------------------------------------------------------------
-----------------------------------------------------------------------
亨利·王(somethingweird)弘
CentOS 7.0 – Apache 2.4.6 兼容补丁版本适用于 apachebuddy.pl。
curl https://raw.githubusercontent.com/somethingweird/apachebuddy.pl/master/apachebuddy.pl | perl
Apache2 伙伴
理查德·福斯(@richardforth)对Apache Buddy的修改版本。
该版本将物理内存除以Apache进程的平均内存,并将其的90%作为MaxClients的容忍范围,不考虑子进程的共享内存等。
由于使用了netstat命令,因此在RHEL / CentOS 7.x上需要事先执行yum install net-tools来安装。
curl -sL apache2buddy.pl -o apache2buddy.pl
perl apache2buddy.pl -r
[ CRITICAL ] Going by the average Apache process, Apache can potentially use 1354.25 MB RAM:
Without considering services: 136.38 % of total installed RAM
Considering extra services: 136.38 % of remaining RAM
[ CRITICAL ] Going by the largest Apache process, Apache can potentially use 1354.25 MB RAM:
Without considering services: 136.38 % of total installed RAM
Considering extra services: 136.38 % of remaining RAM
--------------------------------------------------------------------------------
Apache2buddy.pl report for server: localhost (14.3.31.162):
Settings considered for this report:
Your server's physical RAM: 993 MB
Remaining Memory after other services considered: 993 MB
Apache's MaxClients directive: 256 <--------- Current Setting
Apache MPM Model: prefork
[ !! ] Your MaxRequestWorkers setting is too high.
Your recommended MaxRequestWorkers setting is between 168 and 187. <------- Acceptable Range (10% of MAX)
Max potential memory usage: 1354 MB
Percentage of TOTAL RAM allocated to Apache: 136.38 %
Percentage of REMAINING RAM allocated to Apache: 136.38 %
--------------------------------------------------------------------------------
子进程内存输出
共享内存大小.pl(naoya版)
使用Linux::Smaps的脚本shared_memory_size.pl经常被引用,但是为了方便,最好使用其他脚本。
cat << _EOF_ > shared_memory_size.pl
#!/usr/bin/env perl
use strict;
use warnings;
use Linux::Smaps;
@ARGV or die "usage: %0 [pid ...]";
printf "PID\tRSS\tSHARED\n";
for my \$pid (@ARGV) {
my \$map = Linux::Smaps->new(\$pid);
unless (\$map) {
warn \$!;
next;
}
printf
"%d\t%d\t%d (%d%%)\n",
\$pid,
\$map->rss,
\$map->shared_dirty + \$map->shared_clean,
int(((\$map->shared_dirty + \$map->shared_clean) / \$map->rss) * 100)
}
_EOF_
perl shared_memory_size.pl `pgrep httpd`
PID RSS SHARED
4847 8272 6180 (74%)
4876 5544 5292 (95%)
4935 5544 5292 (95%)
4976 5544 5292 (95%)
4999 5544 5292 (95%)
shared_memory_size.pl (yumatsumo版本)
Linux::Smaps 无用版本。
cat << _EOF_ > shared_memory_size.pl
#!/bin/env perl
use strict;
use warnings;
use List::Util ();
@ARGV or die "usage: %0 [pid ...]";
my @output;
for my \$pid (@ARGV) {
die "invalid pid '\$pid'" if \$pid =~ /\D/;
my @smaps = \`cat /proc/\$pid/smaps\`;
die if \$? != 0;
my @shared = map { /(\d+)\s+kB/; \$1 } grep { /^Shared_(Clean|Dirty)/ } @smaps;
my \$shared_total = List::Util::sum(@shared);
my @rss = map { /(\d+)\s+kB/; \$1 } grep { /^Rss/ } @smaps;
my \$rss_total = List::Util::sum(@rss);
my \$parcent = sprintf '(%d %%)', int((\$shared_total / \$rss_total) * 100);
push @output, [\$pid, \$rss_total, \$parcent];
}
unshift @output, [qw(PID RSS SHARED)];
for my \$out (@output) {
print join "\t", @\$out;
print "\n";
}
_EOF_
perl shared_memory_size.pl `pgrep httpd`
PID RSS SHARED
2505 3460 (75 %)
2506 2960 (93 %)
2507 2960 (93 %)
2508 2960 (93 %)
2509 2960 (93 %)
2510 2960 (93 %)
获取内存.sh / 获取共享内存.sh.
调查Apache的内存使用量 – satooshi@blog
运行getmem.sh
cat << _EOF_ > getmem.sh
#!/bin/sh
#1 process name
if [ \$# -ne 1 ]; then
exit
fi
# print header
printf "PID\tVmPeak\tVmSize\tVmHWM\tVmRSS\n"
# get memory size
pid=\`pgrep \$1\`
for p in \$pid
do
if [ -f /proc/\$p/status ]; then
vm=\`grep -e '^VmPeak:\|VmSize:\|VmHWM:\|VmRSS:' /proc/\$p/status | awk '{print \$2}'\`
printf "%d\t%d\t%d\t%d\t%d\n" \$p \$vm
fi
done
_EOF_
sh getmem.sh httpd
PID VmPeak VmSize VmHWM VmRSS
2193 307688 307688 11828 11828
2194 307708 307688 6096 6096
2195 307708 307688 6096 6096
2196 307708 307688 6096 6096
2197 307708 307688 6096 6096
2198 307708 307688 6096 6096
获取共享内存.sh
cat << _EOF_ > getshmem.sh
#!/bin/sh
# \$1 process name
if [ \$# -ne 1 ]; then
exit
fi
# print header
printf "PID\tRSS\tSHARED\n"
# get shared memory size
pid=\`pgrep \$1\`
for p in \$pid
do
if [ -f /proc/\$p/smaps ]; then
vm=\`grep -e '^Rss:\|^Shared_Clean:\|^Shared_Dirty:' /proc/\$p/smaps |
awk '
BEGIN {
rss = 0;
clean = 0;
dirty = 0;
}
{
if(\$1 == "Rss:") {
rss += \$2;
}
else if(\$1 == "Shared_Clean:") {
clean += \$2;
}
else if(\$1 == "Shared_Dirty:") {
dirty += \$2;
}
}
END {
per = (rss == 0) ? 0 : (clean+dirty)*100/rss;
printf("%d\t%d\t%d\n", rss, clean+dirty, per);
}
'\`
printf "%d\t%d\t%d (%d%%)\n" \$p \$vm
fi
done
_EOF_
sh getshmem.sh httpd
PID RSS SHARED
2193 11832 8368 (70%)
2194 6208 6012 (96%)
2195 6208 6016 (96%)
2196 6208 6016 (96%)
2197 6208 6016 (96%)
2198 6208 6016 (96%)
smaps.sh 文件
以下是同样意思的中文表达:
holly的博客:2010年9月23日的技术方案
这是Shell脚本版本,不需要Perl或Linux::Smaps。
单位采用KB,增加了VSZ(虚拟内存大小)作为项目。
cat << _EOF_ > smaps.sh
#!/bin/sh
echo -e "PID\tVSZ\t\tRSS\tShared"
for pid in \$@; do
smaps="/proc/\$pid/smaps"
vsz=\$(grep -E "^Size" \$smaps | awk 'BEGIN{ num = 0 } { num += \$2 } END{ print num }')
rss=\$(grep -E "^Rss" \$smaps | awk 'BEGIN{ num = 0 } { num += \$2 } END{ print num }')
shared=\$(grep -E "^Shared" \$smaps | awk 'BEGIN{ num = 0 } { num += \$2 } END{ print num }')
percent=\$(echo "scale=2; (\$shared / \$rss) * 100" | bc | cut -d "." -f 1)
echo -e "\$pid\t\${vsz}KB\t\${rss}KB\t\${shared}KB(\${percent}%)"
done
_EOF_
sh smaps.sh `pgrep httpd`
PID VSZ RSS Shared
4847 232840KB 8272KB 6180KB(74%)
4876 232840KB 5544KB 5292KB(95%)
4935 232840KB 5544KB 5292KB(95%)
4976 232840KB 5544KB 5292KB(95%)
4999 232840KB 5544KB 5292KB(95%)
没有共享内存的数据获取器.pl
与其计算和输出VSZ,而是计算和输出NONE_SHARED。
cat << _EOF_ > none_shared_memory_fetcher.pl
#!/usr/bin/env perl
use strict;
use warnings;
@ARGV or die "usage: %0 [pid ...]";
printf "PID\tRSS\tSHARED\tNONE_SHARED\n";
for my \$pid (@ARGV) {
open my \$fh, "< /proc/\$pid/smaps" or (warn \$! and next);
my @rows = <\$fh>;
my \$rss = mem_size_fetcher('Rss',@rows) or next;
my \$shared = mem_size_fetcher('Shared_Clean',@rows) + mem_size_fetcher('Shared_Dirty',@rows);
printf
"%d\t%d\t%d (%d%%)\t%d\n",
\$pid,
\$rss,
\$shared,
int((\$shared / \$rss) * 100),
(\$rss - \$shared),
}
sub mem_size_fetcher {
my (\$target,@rows) = @_;
my \$mem_size = 0;
for my \$row (@rows) {
my (\$mem) = \$row =~ /^\$target:\s*(\d+)/i;
\$mem_size +=(\$mem||0);
}
return \$mem_size;
}
_EOF_
perl none_shared_memory_fetcher.pl `pgrep httpd`
PID RSS SHARED NONE_SHARED
12538 3780 3072 (81%) 708
12540 3048 2836 (93%) 212
12541 3060 2840 (92%) 220
12542 3152 2908 (92%) 244
12543 3060 2840 (92%) 220
12544 3048 2836 (93%) 212
12545 3060 2840 (92%) 220
12546 3060 2840 (92%) 220
12547 3060 2840 (92%) 220
自动计算
获取最大客户端.php
我创建了一个用于计算Apache的MaxClient的脚本 – 网络话题
curl -sL https://raw.githubusercontent.com/ryoppy/Get-MaxClients./master/get_max_client.php | php
--------------------------------
memorySize / (rssAverage - shrAverage) = 1020076KB / (5673KB - 5364KB) = 3301
MaxClient maximum value is 3301.
--------------------------------
肯吉的叉子
curl -sL https://raw.githubusercontent.com/kenjis/Get-MaxClients./my_change/get_max_client.php | php
--------------------------------
rssAverage - shrAverage = (5673KB - 5364KB) = 309KB
memorySize / (rssAverage - shrAverage) = 1020076KB / 309KB = 3301
MaxClient maximum value is 3301.
--------------------------------
获取最大客户端.sh
Apache调优:计算可以设置的MaxClients上限值 – (DxD)∞
get_max_client.php的Shell脚本版本。关于$_MIN_MAX_CLIENTS请参考以下内容。
该计算是根据可用内存量来确定MaxClients。然而,它并没有考虑已启动的Apache进程所使用的内存量,因此是不完整的。
cat << _EOF_ > get_max_clients.sh
#!/bin/bash
_PIDS=(\`pgrep httpd\`)
_PROC_COUNT=\${#_PIDS[@]}
_MEMORY_TOTAL=\`free | grep Mem | awk '{print \$2;};'\`
_MEMORY_FREE=\`vmstat -a | awk 'NR==3{print \$4+\$5;};'\`
_RSS_TOTAL=0
_SHARED_TOTAL=0
for _PID in \${_PIDS[@]}; do
_SMAPS=\`cat /proc/\$_PID/smaps\`
_RSS=\`echo "\$_SMAPS" | grep Rss | awk '{value += \$2} END {print value;};'\`
_SHARED=\`echo "\$_SMAPS" | grep Shared | awk '{value += \$2} END {print value;};'\`
_RSS_TOTAL=\`expr \$_RSS_TOTAL + \$_RSS\`
_SHARED_TOTAL=\`expr \$_SHARED_TOTAL + \$_SHARED\`
done
_RSS_AVERAGE=\`expr \$_RSS_TOTAL / \$_PROC_COUNT\`
_SHARED_AVERAGE=\`expr \$_SHARED_TOTAL / \$_PROC_COUNT\`
_PROC_MEMORY=\`expr \$_RSS_AVERAGE - \$_SHARED_AVERAGE\`
_MIN_MAX_CLIENTS=\`expr \$_MEMORY_FREE / \$_PROC_MEMORY\`
_MAX_MAX_CLIENTS=\`expr \$_MEMORY_TOTAL / \$_PROC_MEMORY\`
echo "Memory Total / (Rss Average - Shr Average) = \$_MEMORY_TOTAL / (\$_RSS_AVERAGE - \$_SHARED_AVERAGE)"
echo "Memory Free / (Rss Average - Shr Average) = \$_MEMORY_FREE / (\$_RSS_AVERAGE - \$_SHARED_AVERAGE)"
echo "MaxClients = \$_MIN_MAX_CLIENTS ~ \$_MAX_MAX_CLIENTS"
exit 0
_EOF_
sh get_max_clients.sh
Memory Total / (Rss Average - Shr Average) = 1020076 / (3626 - 3263)
Memory Free / (Rss Average - Shr Average) = 635560 / (3626 - 3263)
MaxClients = 1750 ~ 2810
Apache 相关信息
-
- Apacheセキュリティ設定
-
- Apache HTTP Server のサポート期限
-
- Apache のログをコマンドラインで集計する
-
- Apache の情報をコマンドラインで取得する
-
- IPアドレスから国や都市を判別する (GeoIP)
-
- Apache チューニング スクリプト
- Apache の MaxClients の適正値