即使只有一个用户,Apache 也会使用 100% 的 CPU
每次有人在我们的错误跟踪器上搜索错误或只是重新加载搜索结果页面或只是对结果进行排序时,Apache(或者我应该说通过 Apache 的 PHP?)都会使用 100% 的 CPU 几秒钟。
这会导致页面加载速度非常慢。即使我从服务器机器本身访问我们的错误跟踪器,也会发生这种情况。
我的问题是这里的瓶颈是什么(apache 配置、php 配置、mysql 配置、缓存、php 模块还是其他什么?)以及我应该尝试做什么来解决它?
我们正在使用的软件(几个月前下载,此后没有更新):
Ubuntu:14.04.3 LTS
PHP:5.5.9(我猜是作为 apache mod?CGI?似乎不是 fastCGI)
apache2:2.4.7 (PREFORK)
mysql: 5.5.44
Bug Genie(错误跟踪软件):4.1.0
这是 Firebug 的图像。
“POST paginated” 是重量级的,它需要 1 秒才能接收 4.0M,但是必须等待 7 秒才能接收。
这是“POST 分页”标题的图像。
至于服务器,它是这样做的。
看起来“分页”请求需要7-8秒才能处理。
第一波是我搜索并显示大约 250 个问题(“POST 分页”),第二波是我执行一个小操作(例如转到一个问题页面)。你可以看到,即使是很小的操作也会占用大量 CPU。
即使我不访问错误跟踪器,我也不知道为什么使用了这么多内存(2.0G 中的 1.6G),但无论如何,可用内存似乎足够了。
似乎没有 I/O 问题(“%iowait”较低,“await”有时会大于“svctm”,但只是有时)
而且看起来,并没有出现太多的交换。
这是我们的设置(据我猜测这部分可能很重要)。
Apache2.conf(不使用 httpd.conf)
ServerName localhost
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
HostnameLookups Off
<Directory /var/www/html/bugs2/>
Options Indexes MultiViews
AllowOverride All
Order allow,deny
Allow from all
</Directory>
AccessFileName .htaccess
将 ServerName 更改为 127.0.0.1 没有帮助。
我还尝试将以下文本添加到 apache.conf,但它不会改变任何东西。我猜是因为已经有 mpm_prefork.conf 了,它非常接近(只有 MaxRequestWorkers 是 150)。
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 20
MaxRequestsPerChild 0
</IfModule>
.htaccess
<IfModule mod_php5.c>
php_flag magic_quotes_gpc off
php_flag register_globals off
</IfModule>
Options +FollowSymlinks
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /bugs2/public/
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^(.*)$ index.php?url=$1 [NC,QSA,L]
RewriteCond %{REQUEST_URI} \..+$/
RewriteCond %{REQUEST_URI} !\.(html|wsdl|json|xml)$
RewriteRule .* - [L]
RewriteRule ^(.*)$ index.php?url=$1 [NC,QSA,L]
RedirectMatch 403 ^/\.svn(/|$)
</IfModule>
几天前,我也将下面的 mod_expires、mod_headers、mod_deflate、mod_gzip 放入 .htaccess,但我看不出前后 CPU 使用率或加载速度有任何差异。
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault "access plus 24 hours"
ExpiresByType application/json "access plus 1 months"
ExpiresByType image/jpg "access plus 1 months"
ExpiresByType image/gif "access plus 1 months"
ExpiresByType image/jpeg "access plus 1 months"
ExpiresByType image/png "access plus 1 months"
ExpiresByType text/css "access plus 1 months"
ExpiresByType text/javascript "access plus 1 months"
ExpiresByType application/javascript "access plus 1 months"
ExpiresByType application/x-shockwave-flash "access plus 1 months"
ExpiresByType application/x-javascript "access plus 1 months"
ExpiresByType application/pdf "access plus 1 months"
ExpiresByType image/x-icon "access plus 1 year"
</IfModule>
<ifModule mod_headers.c>
<filesMatch "\\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
Header set Cache-Control "max-age=2592000, public, no-transform"
</filesMatch>
<filesMatch "\\.(css)$">
Header set Cache-Control "max-age=604800, public"
</filesMatch>
<filesMatch "\\.(js)$">
Header set Cache-Control "max-age=216000, private"
</filesMatch>
<filesMatch "\\.(xml|txt)$">
Header set Cache-Control "max-age=216000, public, must-revalidate"
</filesMatch>
<filesMatch "\\.(html|htm|php)$">
Header set Cache-Control "max-age=1, private, must-revalidate"
</filesMatch>
Header unset ETag
Header unset Last-Modified
</ifModule>
<IfModule mod_deflate.c>
SetOutputFilter DEFLATE
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|ico)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI _\.utxt$ no-gzip
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/atom_xml
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/x-httpd-php
AddOutputFilterByType DEFLATE application/json
</IfModule>
<ifModule mod_gzip.c>
mod_gzip_on Yes
mod_gzip_dechunk Yes
mod_gzip_item_include file .(html?|txt|css|js|php|pl|json)$
mod_gzip_item_include handler ^cgi-script$
mod_gzip_item_include mime ^text/.*
mod_gzip_item_include mime ^application/x-javascript.*
mod_gzip_item_exclude mime ^image/.*
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</ifModule>
我也尝试在 mod_expires 部分使用 filesMatch 而不是 ExpiresByType,但也没有帮助。
php配置文件
engine = On
output_buffering = 4096
disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,
disable_classes =
zend.enable_gc = On
expose_php = On
max_execution_time = 30
max_input_time = 60
memory_limit = 128M
顺便说一下,运行 phpinfo() 时我可以看到其他内存限制
但或许这并不重要。
我的cnf
bind-address = localhost
skip-external-locking
skip-name-resolve
key_buffer = 16M
max_allowed_packet = 16M
thread_stack = 192K
thread_cache_size = 8
myisam-recover = BACKUP
query_cache_limit = 1M
query_cache_size = 16M
将绑定地址切换为 127.0.0.1 没有帮助。
已安装 Php 模块
Bcmath
Bz2
Calendar
Core
Ctype
Curl
Date
Dba
Dom
Ereg
Exif
Fileinfo
Filter
ftp
gd
gettext
hash
iconv
json
libxml
mbstring
mhash
mysql
mysqli
openssl
pcntl
pcre
PDO
Pdo_mysql
Phar
Posix
Readline
Reflection
Session
Shmop
SimpleXML
Soap
Sockets
SPL
Standard
Sysvmsg
Sysvsem
Sysvshm
Tokenizer
Wddx
Xml
Xmlreader
Xmlwriter
Zend OPcache
Zip
Zlib
我知道有时 php 模块会导致此类问题,但我还没有尝试逐个阻止它们。另外,我也不太确定,但 OPcache 似乎正在工作。
已安装 Apache 模块
Core_module (static)
So_module (static)
watchdog_module (static)
http_module (static)
log_config_module (static)
version_module (static)
unixd_module (static)
access_compat_module (shared)
alias_module (shared)
auth_basic_module (shared)
authn_core_module (shared)
authn_file_module (shared)
authz_core_module (shared)
authz_host_module (shared)
authz_user_module (shared)
autoindex_module (shared)
deflate_module (shared)
dir_module (shared)
env_module (shared)
filter_module (shared)
mime_module (shared)
mpm_prefork_module (shared)
negotiation_module (shared)
php5_module (shared)
rewrite_module (shared)
setenvif_module (shared)
status_module (shared)
访问和错误日志没有显示任何特殊或可疑的内容。