![Apache2 中的 I/O 速度疑虑](https://linux22.com/image/668096/Apache2%20%E4%B8%AD%E7%9A%84%20I%2FO%20%E9%80%9F%E5%BA%A6%E7%96%91%E8%99%91.png)
以下是我的故事:
我正在致力于改进 develutils.com,我在安装了 Ubuntu 的 Virtualbox 中进行开发,它有 4Gb RAM 和 2 个 4 核处理器。Web 使用自制的 MVC PHP 框架。
我有一个指向 VBox 的本地虚拟主机,并启动测试以使用 apache 测试检查速度:
ab -n 2700 -c 90 -k -H “接受编码:gzip,deflate”http://develutils.ben/
这给了我 38 个请求/秒
好的...这太低了 Req/s,并且在测试期间,VBox HDD 指示器始终亮着,并且 2 个核心不在 100%...
首先,我尝试将机器移至另一个磁盘和 SSD,检查 ab 测试并得到 360 Req/s,好的,这个数字很像我,但这给了我更多疑问......
我尝试确定 I/O 过剩的问题,并使用了以下奇妙的命令:
inotifywait -mr /var/www/Develutils/
这吐了我一下:
/var/www/WEBS/Develutils/ OPEN .htaccess
/var/www/WEBS/Develutils/ ACCESS .htaccess
/var/www/WEBS/Develutils/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/webroot/ OPEN .htaccess
/var/www/WEBS/Develutils/webroot/ ACCESS .htaccess
/var/www/WEBS/Develutils/webroot/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/system/temp/cache/ OPEN LANGUAGE_DICTIONARY_es.tmp
/var/www/WEBS/Develutils/system/temp/cache/ ACCESS LANGUAGE_DICTIONARY_es.tmp
/var/www/WEBS/Develutils/system/temp/cache/ CLOSE_NOWRITE,CLOSE LANGUAGE_DICTIONARY_es.tmp
/var/www/WEBS/Develutils/ OPEN .htaccess
/var/www/WEBS/Develutils/ OPEN .htaccess
/var/www/WEBS/Develutils/ ACCESS .htaccess
/var/www/WEBS/Develutils/ ACCESS .htaccess
/var/www/WEBS/Develutils/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/ OPEN .htaccess
/var/www/WEBS/Develutils/ ACCESS .htaccess
/var/www/WEBS/Develutils/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/ ACCESS .htaccess
/var/www/WEBS/Develutils/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/ OPEN .htaccess
/var/www/WEBS/Develutils/ ACCESS .htaccess
/var/www/WEBS/Develutils/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/webroot/ OPEN .htaccess
/var/www/WEBS/Develutils/webroot/ ACCESS .htaccess
/var/www/WEBS/Develutils/webroot/ OPEN .htaccess
/var/www/WEBS/Develutils/webroot/ ACCESS .htaccess
/var/www/WEBS/Develutils/webroot/ OPEN .htaccess
/var/www/WEBS/Develutils/webroot/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/webroot/ OPEN .htaccess
/var/www/WEBS/Develutils/webroot/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/webroot/ ACCESS .htaccess
/var/www/WEBS/Develutils/webroot/ ACCESS .htaccess
/var/www/WEBS/Develutils/webroot/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/webroot/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/webroot/ OPEN .htaccess
/var/www/WEBS/Develutils/webroot/ ACCESS .htaccess
/var/www/WEBS/Develutils/webroot/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/webroot/templates/bts/css/ OPEN bootstrap-theme.min.css
/var/www/WEBS/Develutils/webroot/js/ OPEN jquery.min.js
/var/www/WEBS/Develutils/ OPEN .htaccess
/var/www/WEBS/Develutils/ ACCESS .htaccess
/var/www/WEBS/Develutils/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/webroot/templates/bts/css/ OPEN bootstrap.min.css
/var/www/WEBS/Develutils/webroot/templates/bts/css/ OPEN bootstrap-datetimepicker.css
/var/www/WEBS/Develutils/webroot/templates/bts/css/ CLOSE_NOWRITE,CLOSE bootstrap-theme.min.css
/var/www/WEBS/Develutils/webroot/templates/bts/css/ OPEN styles.css
/var/www/WEBS/Develutils/webroot/js/ CLOSE_NOWRITE,CLOSE jquery.min.js
/var/www/WEBS/Develutils/webroot/ OPEN .htaccess
/var/www/WEBS/Develutils/webroot/ ACCESS .htaccess
/var/www/WEBS/Develutils/webroot/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/webroot/templates/bts/css/ CLOSE_NOWRITE,CLOSE bootstrap.min.css
/var/www/WEBS/Develutils/webroot/templates/bts/css/ CLOSE_NOWRITE,CLOSE styles.css
/var/www/WEBS/Develutils/ OPEN .htaccess
/var/www/WEBS/Develutils/ ACCESS .htaccess
/var/www/WEBS/Develutils/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/webroot/templates/bts/css/ CLOSE_NOWRITE,CLOSE bootstrap-datetimepicker.css
/var/www/WEBS/Develutils/webroot/ OPEN .htaccess
/var/www/WEBS/Develutils/webroot/js/ OPEN moment.js
/var/www/WEBS/Develutils/webroot/ ACCESS .htaccess
/var/www/WEBS/Develutils/webroot/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/ OPEN .htaccess
/var/www/WEBS/Develutils/ ACCESS .htaccess
/var/www/WEBS/Develutils/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/webroot/js/ CLOSE_NOWRITE,CLOSE moment.js
/var/www/WEBS/Develutils/webroot/ OPEN .htaccess
/var/www/WEBS/Develutils/webroot/ ACCESS .htaccess
/var/www/WEBS/Develutils/webroot/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/webroot/js/ OPEN bootstrap.min.js
/var/www/WEBS/Develutils/webroot/js/ CLOSE_NOWRITE,CLOSE bootstrap.min.js
/var/www/WEBS/Develutils/ OPEN .htaccess
/var/www/WEBS/Develutils/ ACCESS .htaccess
/var/www/WEBS/Develutils/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/ OPEN .htaccess
/var/www/WEBS/Develutils/ ACCESS .htaccess
/var/www/WEBS/Develutils/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/webroot/js/ OPEN handlebars.js
/var/www/WEBS/Develutils/webroot/ OPEN .htaccess
/var/www/WEBS/Develutils/webroot/ ACCESS .htaccess
/var/www/WEBS/Develutils/webroot/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/webroot/ OPEN .htaccess
/var/www/WEBS/Develutils/webroot/ ACCESS .htaccess
/var/www/WEBS/Develutils/webroot/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/webroot/js/ CLOSE_NOWRITE,CLOSE handlebars.js
/var/www/WEBS/Develutils/webroot/js/ OPEN bootstrap-datetimepicker.js
/var/www/WEBS/Develutils/webroot/js/ OPEN web.js
/var/www/WEBS/Develutils/webroot/js/ CLOSE_NOWRITE,CLOSE web.js
/var/www/WEBS/Develutils/webroot/js/ CLOSE_NOWRITE,CLOSE bootstrap-datetimepicker.js
/var/www/WEBS/Develutils/ OPEN .htaccess
/var/www/WEBS/Develutils/ ACCESS .htaccess
/var/www/WEBS/Develutils/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/webroot/ OPEN .htaccess
/var/www/WEBS/Develutils/webroot/ ACCESS .htaccess
/var/www/WEBS/Develutils/webroot/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/ OPEN .htaccess
/var/www/WEBS/Develutils/ ACCESS .htaccess
/var/www/WEBS/Develutils/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/webroot/ OPEN .htaccess
/var/www/WEBS/Develutils/webroot/ ACCESS .htaccess
/var/www/WEBS/Develutils/webroot/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/ OPEN .htaccess
/var/www/WEBS/Develutils/ ACCESS .htaccess
/var/www/WEBS/Develutils/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/webroot/ OPEN .htaccess
/var/www/WEBS/Develutils/webroot/ ACCESS .htaccess
/var/www/WEBS/Develutils/webroot/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/ OPEN .htaccess
/var/www/WEBS/Develutils/ ACCESS .htaccess
/var/www/WEBS/Develutils/ CLOSE_NOWRITE,CLOSE .htaccess
/var/www/WEBS/Develutils/webroot/ OPEN .htaccess
/var/www/WEBS/Develutils/webroot/ ACCESS .htaccess
/var/www/WEBS/Develutils/webroot/ CLOSE_NOWRITE,CLOSE .htaccess
我看到这个,不明白为什么系统读取 .httaccess 这么多次,太多次了,如果文件是一个现有文件(.css、.js、图像等)则需要避免使用 .htaccess,但 apache 调用不断
我有一个包含以下 .htaccess 的基本目录:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^$ webroot/ [L]
RewriteRule (.*) webroot/$1 [L]
</IfModule>
在 webroot 目录中,我有这个:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [L,QSA]
</IfModule>
我有很多问题:
首先,这个 .htaccess 访问正常吗或者我的配置有误?
其次,如果这是“正常”行为,那么 apache 就没有办法缓存它吗?如果这是“正常”行为,我认为可以使用 ramdisk,在系统启动时复制 CMS 文件(仅 CMS 文件和临时目录,而不是图像或任何大文件),然后使用这些目录启动 apache,以将 Req/s 加速到疯狂的数字,但我不知道这是否是一种疯狂行为。
欢迎任何有关此请求速度和 I/O 数量的帮助和评论。
答案1
这就是为什么我将所有内容都放在我的 apache site/mod/port conf 中,它在 apache 启动时加载然后保存在内存中,因此无需额外的磁盘访问。
通过 apache 访问的每个文件都会被读取 .htacces,因此甚至是您网站上的图像和额外内容。
顺便说一下,.htaccess 主要用于共享服务器,以防止滥用用户配置,但让它们比默认配置拥有更多的可能性。
因此,如果您想将 .htaccess 添加到您的网站配置中,您可以使用/etc/apache2/site-enabled/{yoursiteconfig}
<Directory /var/www/WEBS/Develutils/>
RewriteEngine on
RewriteRule ^$ webroot/ [L]
RewriteRule (.*) webroot/$1 [L]
</Directory>
<Directory /var/www/WEBS/Develutils/webrrot/>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [L,QSA]
</Directory>
你必须对每个 .htaccess 都这样做
如果你想进一步减少硬盘访问,你可以在配置中添加一些缓存并删除一些无用的日志
例如从日志中删除图片、css 和 js
SetEnvIf Request_URI "\.jpg$|\.jpeg$|\.gif$|\.png$|\.ico|\.icon|\.css$|\.js$" dontlog
<virtualhost {IP}:{PORT}>
...
CustomLog ${APACHE_LOG_DIR}/access.log combined env=!dontlog
...
</virtualhost>
缓存文件,防止访问文件
#Remove ETags
Header unset ETag
FileETag none
#MOD_DEFLATE COMPRESSION
SetOutputFilter DEFLATE
AddOutputFilterByType DEFLATE text/html text/css text/plain text/xml application/x-javascript application/x-httpd-php
#DEFLATE NOT COMPATIBLE BROWERS
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
#NOT CHACHING IF ALREADY CACHED
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip
#PROXY CHECK CONTENT
Header append Vary User-Agent env=!dont-vary
#CACHE-CONTROL HEADERS
<IfModule mod_headers.c>
<FilesMatch "\.(ico|jpe?g|png|gif|swf|gz|ttf)$">
Header set Cache-Control "max-age=2797200, public"
</FilesMatch>
<FilesMatch "\.(css)$">
Header set Cache-Control "max-age=2797200, public"
</FilesMatch>
<FilesMatch "\.(js)$">
Header set Cache-Control "max-age=2797200, private"
</FilesMatch>
<filesMatch "\.(html|htm)$">
Header set Cache-Control "max-age=86400, public"
</filesMatch>
#Disable caching for scripts and other dynamic files
<FilesMatch "\.(pl|php|cgi|spl|scgi|fcgi)$">
Header unset Cache-Control
</FilesMatch>
</IfModule>
#EXPIRES HEADERS
<IfModule mod_expires.c>
ExpiresActive On
#Images
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
AddType image/x-icon .ico
ExpiresByType image/ico "access plus 1 year"
ExpiresByType image/icon "access plus 1 year"
ExpiresByType image/x-icon "access plus 1 year"
#Elements
ExpiresByType application/xhtml+xml "access plus 1 week"
ExpiresByType text/html "access plus 1 week"
ExpiresByType text/css "access plus 1 week"
ExpiresByType application/javascript "access plus 1 week"
ExpiresByType text/x-javascript "access plus 1 week"
#Others
ExpiresDefault "access plus 1 month"
</IfModule>
答案2
除非您绝对需要(例如,您使用共享主机并且这不是适合您的网站),否则您应该将所有内容移出 .htaccess 并将其放入服务器配置文件中。
如果您使用 AllowOverride 启用了 .htaccess 文件,那么 Apache httpd 必须针对每个请求检查资源路径中的每个目录是否存在 .htaccess 文件。找到的 .htaccess 文件将被打开并读取每一个要求。
再怎么强调也不为过——除非别无他法,否则不要使用 .htaccess 文件。通常,您可以在服务器配置文件中完成所有需要的操作。