如何检查 apache & php-fpm 配置是否合适(不要太高或太低)
How check apache & php-fpm config is appropriate (not too high or too low)
我将在应用程序(php 基数)上与 3k 用户举办活动。
我在云端启动了几个实例并在上面安装了 LAMP。[进行负载测试并为事件选择开启]
上Ubuntu18
我启用了 mpm_event 和 php7.4-fpm,( 这似乎是使用 apache 和 php app[=47 的高流量的更好配置=]).
我使用 this post 来解释如何调整你的 conf。
像这样:
这里是 apache2 mpm 事件配置文件:
<IfModule mpm_*_module>
ServerLimit (Total RAM - Memory used for Linux, DB, etc.) / process size
StartServers (Number of Cores)
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers (Total RAM - Memory used for Linux, DB, etc.) / process size
MaxConnectionsPerChild 1000
</IfModule>
这里 php7.4-fpm :
pm = dynamic
pm.max_children (total RAM - (DB etc) / process size)
pm.start_servers (cpu cores * 4)
pm.min_spare_servers (cpu cores * 2)
pm.max_spare_servers (cpu cores * 4)
pm.max_requests 1000
我的目标是:即使我依赖这些方法,我也会看到一些指标,例如:
- --> 你有太多线程(来自 apache worker 或来自 phpfpm)未使用 open
- --> 你所有的线程(来自 apache worker 或来自 phpfpm)已经很忙并且使用
我已经测试过:htop、glance、vmstat、sar 来检查 io、cpu、ram,但即便如此我也不清楚:
我的配置是否适合这个负载的机器,或者我应该 increase/decrease 什么?
然后我可以确定这些配置是好的,然后开始其他主题:CDN,缓存 ...
你是如何管理的?
提前致谢,
没有工具会为您提供那种指标,因为最佳配置在很大程度上取决于您的 php 脚本。如果你有 4 个内核,并且每个请求在 1 秒内消耗一个内核的 100%,那么无论你的 mpm 和 php 配置如何,服务器在最佳情况下每秒将处理 4 个请求。您拥有的硬件类型也很重要。有些 CPU 的表现比其他人好很多倍。
由于您使用的是php_fpm,apache mpm 配置对性能影响不大。您只需要确保服务器不会因请求过多而崩溃,并且 apache 线程数多于 php 个进程数。请注意,RAM 并不是唯一可以使服务器无法访问的东西。尝试执行超过 CPU 可以处理的进程将增加负载和上下文切换的次数,降低 CPU 缓存效率并导致性能更低。
php 进程的理想数量取决于您的脚本如何使用 CPU 和其他资源。例如,如果每个脚本使用 50% 的时间进行 I/O 操作,那么每个核心 2 个进程可能是理想的。假设那些 I/O 操作可以并行完成而不会相互阻塞。
您还需要考虑其他进程(例如数据库)使用的资源量。 SQL 数据库可以轻松使用比 php 脚本本身更多的资源。
Spare Servers
和Spare Threads
是可以空闲等待工作的processes/threads个数。创建线程需要时间,因此最好在请求到达时准备好它们。缺点是即使在空闲时,这些线程也会消耗 RAM 等资源,因此您只希望保持足够的线程处于活动状态。 apache 和 php_fpm 都会自动处理这个问题。空闲线程的数量将根据需要减少和增加,但保持在配置中设置的最小值和最大值之间。请注意,并非所有的 Apache 线程都会为 php 文件提供服务,因为某些请求可能正在获取静态文件,因此您应该始终拥有比 php 个进程更多的 Apache 线程。
Start Server
和 Start Threads
仅表示在启动期间创建的 processes/threads 的数量。这对性能几乎没有影响,因为线程数将立即增加或减少以适应 Spare Threads
.
的值
MaxConnectionsPerChild
和 max_requests
只是在 process/thread 生命周期内执行的最大请求量。除非你有内存泄漏,否则你不需要调整这些值。
如您所述,这取决于您的脚本。我们根据正在汇总的服务器在我们的部署脚本中对此进行了动态调整。
以下脚本基于 运行ning Apache、Centos、AWS 基础设施,但可以很容易地适应您正在使用的内容。
基本上:
- 设置 apache 进程的大小
- 设置php进程的大小
- scripts 获取可用内存、核心并执行一些 c运行ching,然后修改配置。
- 我们运行这是堆栈汇总的一部分
主要来源/基于:
步骤:
- 计算进程大小
您需要知道您的机器上可以 运行 多少个进程。因此,计算主要 CPU/memory 驱动程序的进程大小是必要的。
cd /tmp
curl https://raw.githubusercontent.com/pixelb/ps_mem/master/ps_mem.py --output ps_mem.py
chmod a+x ps_mem.py
sudo python ps_mem.py
# Sample numbers:
# 28.4 MiB + 103.0 KiB = 28.5 MiB memcached
# 34.7 MiB + 9.5 KiB = 34.7 MiB amazon-cloudwatch-agent
# 24.8 MiB + 18.0 MiB = 42.8 MiB httpd (15)
# 69.1 MiB + 7.0 MiB = 76.0 MiB php (2)
# 228.2 MiB + 46.0 MiB = 274.3 MiB php-fpm (36)
在这里您可以看到有 15 个 httpd 进程,总共消耗 43MiB,因此每个 Apache 进程大约使用 3MiB 的 RAM。
php-fpm 进程将使用大约 7.6MiB。
- 计算 Apache MaxRequestWorkers
为了安全起见,为所有其他进程保留 15% 的内存(在我的例子中为 ~1.2GiB)并将 apache 进程大小四舍五入为 3MiB。
MaxRequestWorkers = (Total RAM - Memory used for Linux, DB, etc.) / process size
MaxRequestWorkers = (8000MB - 1200MB) / 3MB = 2,266
- 计算php-fpm max-children
为了安全起见,为所有其他进程保留 1 GiB,并将 php 进程大小四舍五入为 8MiB。
max_children = (Total RAM - Memory used for Linux, DB, etc.) / process size
max_children = (8000MB - 1200MB) / 8MB = 850
- 这是我们在汇总时使用的脚本。
#!/bin/bash
# Creates a configuration script to run once final servers are up.
PROCESS_SIZE_APACHE_MB=3
PROCESS_SIZE_PHP_MB=8
# Get some values from the server
MEMORY_KB=`grep MemTotal /proc/meminfo | awk '"'"'{print }'"'"'`
MEMORY_MB=$(($MEMORY_KB / 1024))
MEMORY_AVAILABLE_MB=$(($MEMORY_KB / 1178))
NUM_CORES=`nproc --all`
echo "Memory: $MEMORY_MB MB"
echo "Memory Available: $MEMORY_AVAILABLE_MB MB"
echo "Num Cores $NUM_CORES"
#Now do some calculations
SERVER_LIMIT=$(($MEMORY_AVAILABLE_MB / $PROCESS_SIZE_APACHE_MB))
echo "HTTP MPM Server Limit: $SERVER_LIMIT"
#Convert Apache from mpm-prefork to mpm-worker
#Set params
#<IfModule mpm_*_module>
# ServerLimit (Total RAM - Memory used for Linux, DB, etc.) / process size
# StartServers (Number of Cores)
# MinSpareThreads 25
# MaxSpareThreads 75
# ThreadLimit 64
# ThreadsPerChild 25
# MaxRequestWorkers (Total RAM - Memory used for Linux, DB, etc.) / process size
# MaxConnectionsPerChild 1000
# </IfModule>
# /etc/httpd/conf.modules.d/00-mpm.conf
echo "
# LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
# LoadModule mpm_worker_module modules/mod_mpm_worker.so
LoadModule mpm_event_module modules/mod_mpm_event.so
<IfModule mpm_*_module>
ServerLimit $SERVER_LIMIT
StartServers $NUM_CORES
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers $SERVER_LIMIT
MaxConnectionsPerChild 1000
</IfModule>
" > /etc/httpd/conf.modules.d/00-mpm.conf
# Configure the workers
# pm = dynamic
# pm.max_children (total RAM - (DB etc) / process size) = 850
# pm.start_servers (cpu cores * 4)
# pm.min_spare_servers (cpu cores * 2)
# pm.max_spare_servers (cpu cores * 4)
# pm.max_requests 1000
MAX_CHILDREN=$(($MEMORY_AVAILABLE_MB / $PROCESS_SIZE_PHP_MB))
echo "Max Children: $MAX_CHILDREN"
NUM_START_SERVERS=$(($NUM_CORES * 4))
NUM_MIN_SPARE_SERVERS=$(($NUM_CORES * 2))
NUM_MAX_SPARE_SERVERS=$(($NUM_CORES * 4))
sed -c -i "s/^;*pm.max_children.*/pm.max_children = $MAX_CHILDREN/" /etc/php- fpm.d/www.conf
sed -c -i "s/^;*pm.start_servers.*/pm.start_servers = $NUM_START_SERVERS/" /etc/php- fpm.d/www.conf
sed -c -i "s/^;*pm.min_spare_servers.*/pm.min_spare_servers = $NUM_MIN_SPARE_SERVERS/" /etc/php-fpm.d/www.conf
sed -c -i "s/^;*pm.max_spare_servers.*/pm.max_spare_servers = $NUM_MAX_SPARE_SERVERS/" /etc/php-fpm.d/www.conf
sed -c -i "s/^;*pm.max_requests = 500.*/pm.max_requests = 1000/" /etc/php-> fpm.d/www.conf
我将在应用程序(php 基数)上与 3k 用户举办活动。
我在云端启动了几个实例并在上面安装了 LAMP。[进行负载测试并为事件选择开启]
上Ubuntu18
我启用了 mpm_event 和 php7.4-fpm,( 这似乎是使用 apache 和 php app[=47 的高流量的更好配置=]).
我使用 this post 来解释如何调整你的 conf。 像这样:
这里是 apache2 mpm 事件配置文件:
<IfModule mpm_*_module>
ServerLimit (Total RAM - Memory used for Linux, DB, etc.) / process size
StartServers (Number of Cores)
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers (Total RAM - Memory used for Linux, DB, etc.) / process size
MaxConnectionsPerChild 1000
</IfModule>
这里 php7.4-fpm :
pm = dynamic
pm.max_children (total RAM - (DB etc) / process size)
pm.start_servers (cpu cores * 4)
pm.min_spare_servers (cpu cores * 2)
pm.max_spare_servers (cpu cores * 4)
pm.max_requests 1000
我的目标是:即使我依赖这些方法,我也会看到一些指标,例如:
- --> 你有太多线程(来自 apache worker 或来自 phpfpm)未使用 open
- --> 你所有的线程(来自 apache worker 或来自 phpfpm)已经很忙并且使用
我已经测试过:htop、glance、vmstat、sar 来检查 io、cpu、ram,但即便如此我也不清楚: 我的配置是否适合这个负载的机器,或者我应该 increase/decrease 什么? 然后我可以确定这些配置是好的,然后开始其他主题:CDN,缓存 ...
你是如何管理的? 提前致谢,
没有工具会为您提供那种指标,因为最佳配置在很大程度上取决于您的 php 脚本。如果你有 4 个内核,并且每个请求在 1 秒内消耗一个内核的 100%,那么无论你的 mpm 和 php 配置如何,服务器在最佳情况下每秒将处理 4 个请求。您拥有的硬件类型也很重要。有些 CPU 的表现比其他人好很多倍。
由于您使用的是php_fpm,apache mpm 配置对性能影响不大。您只需要确保服务器不会因请求过多而崩溃,并且 apache 线程数多于 php 个进程数。请注意,RAM 并不是唯一可以使服务器无法访问的东西。尝试执行超过 CPU 可以处理的进程将增加负载和上下文切换的次数,降低 CPU 缓存效率并导致性能更低。
php 进程的理想数量取决于您的脚本如何使用 CPU 和其他资源。例如,如果每个脚本使用 50% 的时间进行 I/O 操作,那么每个核心 2 个进程可能是理想的。假设那些 I/O 操作可以并行完成而不会相互阻塞。
您还需要考虑其他进程(例如数据库)使用的资源量。 SQL 数据库可以轻松使用比 php 脚本本身更多的资源。
Spare Servers
和Spare Threads
是可以空闲等待工作的processes/threads个数。创建线程需要时间,因此最好在请求到达时准备好它们。缺点是即使在空闲时,这些线程也会消耗 RAM 等资源,因此您只希望保持足够的线程处于活动状态。 apache 和 php_fpm 都会自动处理这个问题。空闲线程的数量将根据需要减少和增加,但保持在配置中设置的最小值和最大值之间。请注意,并非所有的 Apache 线程都会为 php 文件提供服务,因为某些请求可能正在获取静态文件,因此您应该始终拥有比 php 个进程更多的 Apache 线程。
Start Server
和 Start Threads
仅表示在启动期间创建的 processes/threads 的数量。这对性能几乎没有影响,因为线程数将立即增加或减少以适应 Spare Threads
.
MaxConnectionsPerChild
和 max_requests
只是在 process/thread 生命周期内执行的最大请求量。除非你有内存泄漏,否则你不需要调整这些值。
如您所述,这取决于您的脚本。我们根据正在汇总的服务器在我们的部署脚本中对此进行了动态调整。
以下脚本基于 运行ning Apache、Centos、AWS 基础设施,但可以很容易地适应您正在使用的内容。
基本上:
- 设置 apache 进程的大小
- 设置php进程的大小
- scripts 获取可用内存、核心并执行一些 c运行ching,然后修改配置。
- 我们运行这是堆栈汇总的一部分
主要来源/基于:
步骤:
- 计算进程大小
您需要知道您的机器上可以 运行 多少个进程。因此,计算主要 CPU/memory 驱动程序的进程大小是必要的。
cd /tmp
curl https://raw.githubusercontent.com/pixelb/ps_mem/master/ps_mem.py --output ps_mem.py
chmod a+x ps_mem.py
sudo python ps_mem.py
# Sample numbers:
# 28.4 MiB + 103.0 KiB = 28.5 MiB memcached
# 34.7 MiB + 9.5 KiB = 34.7 MiB amazon-cloudwatch-agent
# 24.8 MiB + 18.0 MiB = 42.8 MiB httpd (15)
# 69.1 MiB + 7.0 MiB = 76.0 MiB php (2)
# 228.2 MiB + 46.0 MiB = 274.3 MiB php-fpm (36)
在这里您可以看到有 15 个 httpd 进程,总共消耗 43MiB,因此每个 Apache 进程大约使用 3MiB 的 RAM。 php-fpm 进程将使用大约 7.6MiB。
- 计算 Apache MaxRequestWorkers
为了安全起见,为所有其他进程保留 15% 的内存(在我的例子中为 ~1.2GiB)并将 apache 进程大小四舍五入为 3MiB。
MaxRequestWorkers = (Total RAM - Memory used for Linux, DB, etc.) / process size
MaxRequestWorkers = (8000MB - 1200MB) / 3MB = 2,266
- 计算php-fpm max-children
为了安全起见,为所有其他进程保留 1 GiB,并将 php 进程大小四舍五入为 8MiB。
max_children = (Total RAM - Memory used for Linux, DB, etc.) / process size
max_children = (8000MB - 1200MB) / 8MB = 850
- 这是我们在汇总时使用的脚本。
#!/bin/bash # Creates a configuration script to run once final servers are up. PROCESS_SIZE_APACHE_MB=3 PROCESS_SIZE_PHP_MB=8 # Get some values from the server MEMORY_KB=`grep MemTotal /proc/meminfo | awk '"'"'{print }'"'"'` MEMORY_MB=$(($MEMORY_KB / 1024)) MEMORY_AVAILABLE_MB=$(($MEMORY_KB / 1178)) NUM_CORES=`nproc --all` echo "Memory: $MEMORY_MB MB" echo "Memory Available: $MEMORY_AVAILABLE_MB MB" echo "Num Cores $NUM_CORES" #Now do some calculations SERVER_LIMIT=$(($MEMORY_AVAILABLE_MB / $PROCESS_SIZE_APACHE_MB)) echo "HTTP MPM Server Limit: $SERVER_LIMIT" #Convert Apache from mpm-prefork to mpm-worker #Set params #<IfModule mpm_*_module> # ServerLimit (Total RAM - Memory used for Linux, DB, etc.) / process size # StartServers (Number of Cores) # MinSpareThreads 25 # MaxSpareThreads 75 # ThreadLimit 64 # ThreadsPerChild 25 # MaxRequestWorkers (Total RAM - Memory used for Linux, DB, etc.) / process size # MaxConnectionsPerChild 1000 # </IfModule> # /etc/httpd/conf.modules.d/00-mpm.conf echo " # LoadModule mpm_prefork_module modules/mod_mpm_prefork.so # LoadModule mpm_worker_module modules/mod_mpm_worker.so LoadModule mpm_event_module modules/mod_mpm_event.so <IfModule mpm_*_module> ServerLimit $SERVER_LIMIT StartServers $NUM_CORES MinSpareThreads 25 MaxSpareThreads 75 ThreadLimit 64 ThreadsPerChild 25 MaxRequestWorkers $SERVER_LIMIT MaxConnectionsPerChild 1000 </IfModule> " > /etc/httpd/conf.modules.d/00-mpm.conf # Configure the workers # pm = dynamic # pm.max_children (total RAM - (DB etc) / process size) = 850 # pm.start_servers (cpu cores * 4) # pm.min_spare_servers (cpu cores * 2) # pm.max_spare_servers (cpu cores * 4) # pm.max_requests 1000 MAX_CHILDREN=$(($MEMORY_AVAILABLE_MB / $PROCESS_SIZE_PHP_MB)) echo "Max Children: $MAX_CHILDREN" NUM_START_SERVERS=$(($NUM_CORES * 4)) NUM_MIN_SPARE_SERVERS=$(($NUM_CORES * 2)) NUM_MAX_SPARE_SERVERS=$(($NUM_CORES * 4)) sed -c -i "s/^;*pm.max_children.*/pm.max_children = $MAX_CHILDREN/" /etc/php- fpm.d/www.conf sed -c -i "s/^;*pm.start_servers.*/pm.start_servers = $NUM_START_SERVERS/" /etc/php- fpm.d/www.conf sed -c -i "s/^;*pm.min_spare_servers.*/pm.min_spare_servers = $NUM_MIN_SPARE_SERVERS/" /etc/php-fpm.d/www.conf sed -c -i "s/^;*pm.max_spare_servers.*/pm.max_spare_servers = $NUM_MAX_SPARE_SERVERS/" /etc/php-fpm.d/www.conf sed -c -i "s/^;*pm.max_requests = 500.*/pm.max_requests = 1000/" /etc/php-> fpm.d/www.conf