1GB VPS - Apache Worker MPM - FCGID - 最大并发连接数 - RAM CAP

1GB VPS - Apache Worker MPM - FCGID - 最大并发连接数 - RAM CAP

我花了一两周的时间研究和设置我的服务器,以便使用 Worker MPM 和 FCID 运行 Apache。我正在尝试对其进行优化,以允许尽可能多的并发连接。寻找有关 Worker MPM 的有用信息简直是一场噩梦。

服务器——具有 1GB RAM 的 VPS(关闭 Apache 时仅使用大约 150MB 的 RAM)我希望 Apache 的内存使用量上限为 750MB 左右——这样我的服务器就永远不会耗尽 RAM。

我已经运行该服务器大约 2 年了,没有任何问题 - 但我们最近开始流式传输 MP3,这需要更多并发连接。该服务器还遭受过几次小型 DDOS 攻击 - 所以我大幅缩减了设置,以防止服务器内存耗尽 - 我还添加了一些防火墙规则来限制速率。

我现在的设置看起来运行良好 - 但我收到了一些分段错误

[Sat Mar 23 03:19:50 2013] [notice] child pid 28351 exit signal Segmentation fault (11)
[Sat Mar 23 03:56:20 2013] [notice] child pid 29740 exit signal Segmentation fault (11)
*** glibc detected *** /usr/sbin/httpd.worker: malloc(): memory corruption: 0xb83abdd8 ***

还有一些内存不足错误

Out of memory during array extend.

这是我目前的设置,我真的很需要一些建议。

Apache 设置:

Timeout 30
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 2
#####################
# Spawn 2 child processes, spawning 25 threads for each child process.
# So, a pool of 50 threads is left up and sleeping, ready to serve incoming requests.
# If more requests will come in, apache will spawn new child processes, each one spawning 25 threads,
# enlarging the thread pool until the total number of threads become 50. In that case, apache begin
# to cleanly drop processes, trying to reach 25 threads.
# New processes and its threads are spawned in case of a large spike of requests, until 200 parallel
# client requests are reached, then apache will no longer accept new incoming connections.
# When the load calm down, and requests come back under 200 parallel connections, apache will continue
# to accept connections. After 25, 000 requests served by a child, q. 1000 per thread, the process
# get closed by the father to ensure no memory leak is fired.
<IfModule worker.c>
ServerLimit      16
StartServers         2
MaxClients       400
MinSpareThreads   25
MaxSpareThreads  50 
ThreadsPerChild    25
MaxRequestsPerChild  1000
ThreadLimit          64 
ThreadStackSize      1048576
</IfModule>
#####################

然后在fcgid.conf中进行一些设置

FcgidMinProcessesPerClass 0 
FcgidMaxProcessesPerClass 8 
FcgidMaxProcesses  25
FcgidIdleTimeout 60 
FcgidProcessLifeTime 120 
FcgidIdleScanInterval 30

根据要求我对 /etc/my.cnf 的输出

[mysqld]
数据目录=/var/lib/mysql
套接字=/var/lib/mysql/mysql.sock
用户=mysql

#skip-innodb

连接超时 = 10
最大连接数 = 300
符号链接=0
innodb_file_per_table = 1
myisam_sort_buffer_size = 8M
读取缓冲区大小 = 512K
网络缓冲区长度 = 8K
读取缓冲区大小 = 256K
排序缓冲区大小 = 512K
表缓存 = 32
最大允许数据包 = 1M
密钥缓冲区 = 16k
query_cache_type = 1
查询缓存大小 = 32M
线程缓存大小 = 16
网络缓冲区长度 = 2K
线程堆栈 = 256K
等待超时 = 300

慢查询日志

#log-slow-queries=/var/log/mysql/slow-queries.log
slow_query_log=/var/log/mysql/slow-queries.log
长查询时间 = 1

[mysqld_safe]
日志错误=/var/log/mysqld.log
pid 文件=/var/run/mysqld/mysqld.pid

并且 PHP memory_limit = 64M

答案1

这些设置都是为了平衡,你可以将它们设置到多高而不会冒着内存耗尽和服务器崩溃的风险,或者让你的进程被 vps 父进程杀死,这可能是你得到 SegFaults 的原因。

通常,当我优化服务器时,我会运行 mysql tuning-primer.sh 脚本来了解 MySQL 最多可以使用多少内存:

https://launchpad.net/mysql-tuning-primer

然后,对于 prefork,我会将 MaxClients 乘以 php memory_limit,以了解 Apache+PHP 最多可以使用多少内存。这些是粗略的估计,但一旦你做了很多次,你就会对此有所了解。

我尝试将这两项的总和保持在服务器的最大内存附近,如果你的 VPS 没有交换分区,我肯定会尝试将其保持在最大内存以下,原因如下:

1)服务器上的其他进程将使用内存

2)服务器上的某些 php 脚本可能正在使用 ini_set 来更改自身的 memory_limit。

如果您可以提供 /etc/my.cnf 和 php memory_limit,我可能会为您提供一些好的设置。


编辑:我只是想说一下,我知道你使用的是 worker 而不是 prefork,同样的概念也适用,但 worker 必须处理线程,而不仅仅是 MaxClients,所以 prefork 是一个更好的例子。我必须在获得所需信息后查看设置,以便给你提供好的建议

答案2

您可以尝试使用 apache2buddy.pl 脚本来调整您的 Web 应用程序和系统的 apache 设置。

忘记该问题的另一种方法是创建单节点 docker swarm 集群并容器化您的应用程序 - 如果发生内存中断,docker 将在终止 apache 容器并重新启动它...

相关内容