27

我正在运行带有 768mb 内存的 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>

使用我看到的顶部

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

今天早上我的内存缓存服务器死于

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/memcached

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
4

4 回答 4

39

当您将 Apache 与 mod_php 一起使用时,apache 在prefork模式下强制执行,而不是worker. 因为,即使已知 php5 支持多线程,也知道某些 php5 库在多线程环境中表现不佳(例如,您将在一个线程上进行区域设置调用,从而改变其他 php 线程上的区域设置) .

因此,如果 php 没有像 php-fpm 那样以 cgi 方式运行,那么您在 apache 中拥有 mod_php,而 apache 则处于 prefork 模式。在您的测试中,您只是评论了 prefork 设置并增加了 worker 设置,您现在拥有的是 prefork 设置的默认值和共享设置的一些更改值:

StartServers       20
MinSpareServers    5
MaxSpareServers    10
MaxClients         1024
MaxRequestsPerChild  0

这意味着您要求 apache 从 20 个进程开始,但您告诉它,如果有超过 10 个进程什么都不做,它应该减少这个子进程的数量,以保持 5 到 10 个进程可用。apache的增减速度是每分钟1次。所以很快你就会回到经典的情况,你有相当少的免费可用 apache 进程(平均 2 个)。平均值很低,因为通常您有 5 个可用进程,但是一旦流量增长,它们就会全部被使用,因此没有可用的进程,因为 apache 在创建新分支时非常慢。这肯定是因为您的 PHP 请求似乎很长,它们没有提前完成,并且 apache 分支没有足够快地释放来处理另一个请求。

在最后一张图中看到红色峰值之前的少量绿色了吗?如果您可以在 1 分钟而不是 5 分钟的基础上绘制此图,您会发现这个绿色量不足以接收传入流量而不会出现任何错误消息。

现在你设置1024 MaxClients. 我猜想在这个配置修改之后没有拍摄仙人掌图,因为通过这样的修改,当没有更多的进程可用时,apache 会继续 fork 新的孩子,限制为 1024 个忙碌的孩子。每个孩子需要 20MB 的 RAM(或者你在 PHP 中有一个很大的 memory_limit 并允许 64MB 或 256MB 之类的东西,而这些 PHP 请求确实使用了更多的 RAM),也许是一个数据库服务器......你的服务器现在变慢了,因为您只有 768MB 的 RAM。也许当 apache 尝试启动前 20 个孩子时,您已经达到了可用 RAM 限制。

所以。一种经典的处理方法是检查 apache fork 使用的内存量(在它运行时执行一些顶级命令),然后找到使用这个 RAM 量可以处理多少并行请求(这意味着并行 apache 子前叉模式)。例如,假设它是12。以这种方式将此数字放入 apache mpm 设置中:

<IfModule prefork.c>
  StartServers       12
  MinSpareServers    12
  MaxSpareServers    12
  MaxClients         12
  MaxRequestsPerChild  300
</IfModule>

这意味着您不会在流量增加或减少时移动分叉的数量,因为您总是希望使用所有 RAM 并为流量高峰​​做好准备。这300意味着您在 300 个请求后回收每个 fork,它比 0 好,这意味着您不会有潜在的内存泄漏问题。MaxClients 设置为 12 25 或 50 大于 12 来处理ListenBacklog队列,这可以将一些请求排入队列,您可能会占用更大的队列,但您可能会遇到一些超时(删除了这个奇怪的 sentende,我不记得为什么我说过,如果传入的请求超过 12 个,则下一个请求将被推送到 Backlog 队列中,但您应该将 MaxClient 设置为您的目标进程数)。

是的,这意味着您不能处理超过 12 个并行请求。

如果要处理更多请求:

  • 多买一些内存
  • 尝试在工作模式下使用 apache,但删除 mod_php 并将 php 用作具有自己的池设置(这称为php-fpm)的并行守护程序,将其与 fastcgi 连接。请注意,您肯定需要购买一些 RAM 以允许大量并行 php-fpm 进程,但可能比 mod_php 少
  • 减少花在你的 php 过程中的时间。从您的仙人掌图中,您必须找到潜在的问题:11:25-11:30 左右的实际流量高峰或一些 php 代码变得非常慢。快速请求将减少并行请求的数量。

如果您的问题确实是流量高峰,则可以使用缓存解决方案,例如代理缓存服务器。如果问题是 PHP 的随机缓慢,那么......这是一个应用程序问题,例如,您是否从 PHP 对另一个站点进行一些 HTTP 查询?

最后,正如@Jan Vlcinsky 所说,您可以尝试nginx,其中 php 只能作为php-fpm使用。如果您无法购买 RAM 并且必须处理绝对值得测试的大流量。

更新:关于内部虚拟连接(如果这是您的问题,但可能不是)。

检查此链接此先前的答案。这是“正常的”,但如果您没有简单的虚拟主机,这些请求可能会影响您的主要繁重应用程序,生成缓慢的 http 查询并阻止普通用户访问您的 apache 进程。它们是在正常重新加载或子管理时生成的。

如果您没有一个简单的基本“它可以工作”默认虚拟主机通过一些重写来阻止您的应用程序上的这些请求:

  RewriteCond %{HTTP_USER_AGENT} ^.*internal\ dummy\ connection.*$ [NC]
  RewriteRule .* - [F,L]

更新:

只有一个虚拟主机并不能保护您免受内部虚拟连接的影响,最糟糕的是,您现在可以确定这些连接是在您唯一的虚拟主机上建立的。因此,您应该通过使用重写规则来真正避免对您的应用程序产生副作用。

阅读您的仙人掌图形,您的 apache 似乎不在工作模式下的 prefork 模式错误。在 debian 上运行httpd -lorapache2 -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>
于 2013-10-17T12:31:30.170 回答
1

这是一种可以解决您的问题的方法,如果不能,则有助于进行故障排除。

  1. 创建与当前相同的第二个 Apache 虚拟服务器

  2. 将所有“正常”用户流量发送到原始虚拟服务器

  3. 将特殊或长时间运行的流量发送到新的虚拟服务器

特殊或长期运行的流量可能是报告生成、维护操作或您不希望在 <<1 秒内完成的任何其他事情。这可能会发生在服务 API 上,而不仅仅是网页。

如果您的资源利用率很低但仍然超过 MaxClients,最可能的答案是您的新连接到达速度快于它们的服务速度。将任何缓慢的操作放在第二个虚拟服务器上将有助于证明情况是否如此。使用 Apache 访问日志来量化效果。

于 2013-10-17T14:21:27.300 回答
1

您是否考虑过使用 nginx(或其他基于事件的 Web 服务器)而不是 apache?

nginx 应该允许更多的连接并消耗更少的资源(因为它是基于事件的并且不会为每个连接创建单独的进程)。无论如何,您将需要一些进程来完成实际工作(例如 WSGI 服务器等),如果它们与前端 Web 服务器位于同一服务器上,您只会将性能问题转移到稍微不同的地方。

最新的 apache 版本应允许类似的解决方案(以基于事件的方式配置),但这不是我的专业领域。

于 2013-10-17T01:04:51.767 回答
0

我建议使用 Apache 上建议的波纹管公式:

MaxClients =(总 RAM - 操作系统的 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
于 2017-10-03T21:11:02.550 回答