Apache szybszy od innych
Z Fedora Wiki
Jest to poradnik który pozwala znacznie przyspieszyć działanie serwera Apache. Dla mało zaawansowanych użytkowników, posiadających zwykłe serwery intranetowe itp. - polecam tylko krok 2. Najbardziej odczuwalna różnica jest przy tym kroku w takiej skali.
Krok 1. Kopia zapasowa konfiguracji.
cd /root tar -czf httpd_konfiguracja.tar.gz /etc/httpd
Krok 2. Instalacja php_accelerator
yum install php_eaccelerator
Krok 3. Wyłączenie niepotrzebnych modułów
To moja subiektywna lista, po prostu ich nie używam, w przypadku usuwania mod_proxy należy pamiętać o przeniesienie w inne miejsce pliku /etc/httpd/conf.d/proxy_ajp.conf.
Poniższe linie należy oznaczyć hashem (#) na początku.
#LoadModule ldap_module modules/mod_ldap.so #LoadModule authnz_ldap_module modules/mod_authnz_ldap.so #LoadModule env_module modules/mod_env.so #LoadModule dav_module modules/mod_dav.so #LoadModule status_module modules/mod_status.so #LoadModule autoindex_module modules/mod_autoindex.so #LoadModule info_module modules/mod_info.so #LoadModule dav_fs_module modules/mod_dav_fs.so #LoadModule speling_module modules/mod_speling.so #LoadModule userdir_module modules/mod_userdir.so #LoadModule proxy_module modules/mod_proxy.so #LoadModule proxy_balancer_module modules/mod_proxy_balancer.so #LoadModule proxy_ftp_module modules/mod_proxy_ftp.so #LoadModule proxy_http_module modules/mod_proxy_http.so #LoadModule proxy_connect_module modules/mod_proxy_connect.so #LoadModule cgi_module modules/mod_cgi.so
Krok 4. Usunięcie /etc/httpd/conf.d/php.conf (kod php będzie kompilowany w inny sposób).
rm /etc/httpd/conf.d/php.conf
Krok 5. Instalacja mod_fcgid (działa dużo szybciej niż mod_php).
W przypadku Centos`a należy zainstalować repozytorium epel:
su -c 'rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm'
yum install mod_fcgid
Po czym należy wyłączyć repozytorium epel zmieniając w /etc/yum.repos.d/epel.repo enabled na 0
W przypadku fedory:
yum install mod_fcgid
Należy utworzyć plik /var/www/cgi-bin/php.fcgi, oraz nadać atrybut wykonywalności
touch /var/www/cgi-bin/php.fcgi chmod +x /var/www/cgi-bin/php.fcgi
Po otworzeniu pliku /var/www/cgi-bin/php.fcgi poleceniem:
nano /var/www/cgi-bin/php.fcgi
należy wpisać zawartość o postaci:
#!/bin/bash # Shell Script To Run PHP5 using mod_fastcgi under Apache 2.x # Tested under Red Hat Enterprise Linux / CentOS 5.x ### Set PATH ### PHP_CGI=/usr/bin/php-cgi PHP_FCGI_CHILDREN=4 PHP_FCGI_MAX_REQUESTS=1000 ### no editing below ### export PHP_FCGI_CHILDREN export PHP_FCGI_MAX_REQUESTS exec $PHP_CGI
Krok 6. Zawartość pliku /etc/httpd/conf.d/fcgid.conf (najlepiej usunąć zawartość i wpisać ponownie poniższą konfigurację)
LoadModule fcgid_module modules/mod_fcgid.so
<IfModule !mod_fastcgi.c>
AddHandler fcgid-script fcg fcgi fpl
</IfModule>
<Directory /var/www/html> #trzeba zmienić na inny katalog jesli gdzie indziej trzymamy pliki
Options -Indexes FollowSymLinks +ExecCGI
AllowOverride AuthConfig FileInfo
AddHandler php5-fastcgi .php
Action php5-fastcgi /cgi-bin/php.fcgi
DirectoryIndex index.php index.html
Order allow,deny
Allow from all
</Directory>
SocketPath /var/run/mod_fcgid
SharememPath /var/run/mod_fcgid/fcgid_shm
Krok 7. Włączenie cache - w pliku httpd.conf należy dopisać:
CacheDefaultExpire 3600 CacheEnable disk / CacheRoot "/opt/apicache/" CacheDirLevels 2 CacheDirLength 1 CacheMaxFileSize 1000000 CacheMinFileSize 1 CacheIgnoreCacheControl On CacheIgnoreNoLastMod On CacheIgnoreQueryString Off CacheIgnoreHeaders None CacheLastModifiedFactor 0.1 CacheDefaultExpire 3600 CacheMaxExpire 86400 CacheStoreNoStore On CacheStorePrivate On #MOZEMY WYLACZYC CACHE W DOWOLNYM KATALOGU #<IfModule mod_cache.c> #CacheDisable /var/www/html/nocache #</IfModule>.
Krok 8. Włączenie kompresji - w pliku httpd.conf należy wpisać:
<Location /> SetOutputFilter DEFLATE BrowserMatch ^Mozilla/4 gzip-only-text/html BrowserMatch ^Mozilla/4\.0[678] no-gzip #BrowserMatch \bMSI[E]!no-gzip!gzip-only-text/html BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html SetEnvIfNoCase Request_URI \\.(?:gif|jpe?g|png)$ no-gzip dont-vary Header append Vary User-Agent env=!dont-vary </Location>
Krok 9. Tryb worker - w pliku httpd.conf należy dopisać:
<IfModule worker.c> StartServers 32 MaxClients 50 MinSpareThreads 25 MaxSpareThreads 75 ThreadsPerChild 25 MaxRequestsPerChild 0 </IfModule>
Wartości można zmieniać w zależności od potrzeb.
Następnie należy zatrzymać serwer apache:
service httpd stop nano /etc/sysconfig/httpd
W pliku /etc/sysconfig/httpd powinna zdjąć hash z linii (Należy się upewnić że nie ma # na początku):
HTTPD=/usr/sbin/httpd.worker
oraz uruchomić serwer ponownie:
service httpd start
Krok 10: Konfiguracja Selinux
W przypadku problemów z selinuxem należy wykonać polecenia:
grep php-cgi /var/log/audit/audit.log | audit2allow -m phpcgi > phpcgi.te grep php-cgi /var/log/audit/audit.log | audit2allow -M phpcgi semodule -i phpcgi.pp
Wydajność w każdym momencie tutoriala można zmierzyć poleceniem:
ab -n 1000 http://localhost/index.php
Nalepiej zainstalować i testować bardziej skomplikowaną stronę, np. stronę główną wordpressa, sugarcrm, joomla, drupal.
Przykładowy wynik bez poprawek (Sugar CRM)
BEZ POPRAWEK:
Kod
Document Path: /index.php
Document Length: 0 bytes
Concurrency Level: 1
Time taken for tests: 108.312594 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Non-2xx responses: 1000
Total transferred: 556000 bytes
HTML transferred: 0 bytes
Requests per second: 9.23 [#/sec] (mean)
Time per request: 108.313 [ms] (mean)
Time per request: 108.313 [ms] (mean, across all concurrent requests)
Transfer rate: 5.00 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 104 107 4.5 108 238
Waiting: 104 107 4.5 107 238
Total: 104 107 4.5 108 238
Percentage of the requests served within a certain time (ms)
50% 108
66% 108
75% 108
80% 108
90% 109
95% 109
98% 110
99% 111
100% 238 (longest request)
Wyniki po wprowadzeniu poprawek:
Document Path: /index.php
Document Length: 0 bytes
Concurrency Level: 1
Time taken for tests: 13.250858 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Non-2xx responses: 1000
Total transferred: 546000 bytes
HTML transferred: 0 bytes
Requests per second: 75.47 [#/sec] (mean)
Time per request: 13.251 [ms] (mean)
Time per request: 13.251 [ms] (mean, across all concurrent requests)
Transfer rate: 40.22 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 11 12 1.0 13 17
Waiting: 11 12 0.9 13 17
Total: 11 12 1.0 13 17
WARNING: The median and mean for the processing time are not within a normal deviation
These results are probably not that reliable.
WARNING: The median and mean for the waiting time are not within a normal deviation
These results are probably not that reliable.
WARNING: The median and mean for the total time are not within a normal deviation
These results are probably not that reliable.
Percentage of the requests served within a certain time (ms)
50% 13
66% 13
75% 13
80% 13
90% 13
95% 13
98% 13
99% 14
100% 17 (longest request)
Małe uwagi końcowe:
1. Nie wierzcie tak łatwo testom o wyższości prędkości lighttpd, nginx nad apachem Przejrzałem ich trochę w internecie i ogólnie rzecz biorąc ktoś to udowadnia robiąc 1 petlę w php:). Może w takim przypadku jest to szybsze, ale w przypadku obiektowych aplikacji nie ma to większego zastosowania. Podobno lighttpd lepiej serwuje statyczną zawartość, ale co z tego jak ma wycieki pamięci, mniejsze możliwości i praktycznie nie ma wsparcia w przypadku błedów. Z ngnix jest lepiej ale też nie ma możliwości takich jak apache. Może ktoś testował to w jakimś większym środowisku (100 000 użytkowników dziennie) tak więc chętnie usłyszę opinie, aby je tutaj uwzględnić.
2. Nie wprowadzajcie zmian ulepszających nie znane wam parametry bez testów, przekonałem się o tym że jest po nich gorzej. Np. w przypadku mysql, nie znalazłem ani jednej porady która mogłaby przyspieszyć działanie, przynajmniej w moim przypadku, a było gorzej niż na domyślnej konfiguracji.
Podziękowania dla:
wszystkich udzielających się na forach całego świata, piszących artykuły, udzielających się na dev-listach, robiących benchmarki itp itd. bez których ciężko by było zbierać przez lata wiedzę.
Mam nadzieję że komuś się przyda. Jeśli ktoś ma uwagi to chętnie usłyszę. Nie odpowiadam za szkody, robicie to na własną odpowiedzialność najpierw sprawdźcie w środowisku testowym.
