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 の適正値
广告
将在 10 秒后关闭
bannerAds