Skocz do zawartości

Poradnik: Jak Przyspieszyć Serwer Apache + Php 10 Razy !


qmic

Rekomendowane odpowiedzi

EDIT: OPIS JUŻ JEST NA WIKI: http://wiki.fedora.pl/wiki/Apache_szybszy_od_innych i tam będzie aktualizowany

 

Z racji tego że musiałem zrobić małą dokumentację do projektu, postanowiłem trochę podzielić się swoją wiedzą tutaj, aby nie zostało to wszystko schowane do szuflady jak się napracowałem, tak więc postanowiłem stworzyć poradnik dla średnio zaawansowanych użytkowników pomagający przyspieszyć działanie serwera www.

 

Dla mało zaawansowanych użytkowników, posiadających zwykłe serwery intranetowe itp. - polecam tylko punkt 2. Najbardziej odczuwalna różnica jest przy tym kroku w takiej skali.

Przepraszam za formę itp bo nie mogłem wkleić w całości a nie chciało mi się dziś po 8 godzinach robienia testów jeszcze robić tego poradnika zgodnie z zaleceniami :).

 

Zaczynamy!

 

 

1. Robimy kopię zapasową konfiguracji

cd /root
tar -czf httpd_konfiguracja.tar.gz /etc/httpd

 

2. Instalujemy php_eaccelerator

yum install php_eaccelerator

 

3. Wyłączamy niepotrzebne moduły

To moja subiektywna lista, po prostu ich nie używam, w przypadku usuwania mod_proxy nie zapomnij przenieść w inne miejsce pliku /etc/httpd/conf.d/proxy_ajp.conf

#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

 

4. Przenosimy w inne miejsce /etc/httpd/conf.d/php.conf

 

5. Instalujemy mod_fcgid

Dlaczego? W skrócie: Dużo szybsze działanie niż mod_php, mniejsze zużycie pamięci, po prostu nie mogę zrozumieć dlaczego mod_php robią domyślne w dystrybucjach.

W przypadku centosa instalujemy repozytorium epel i instalujemy:

su -c 'rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm'

 

W przypadku fedory wpisujemy tylko

yum install mod_fcgid

 

W przypadku centosa po tym wyłączamy epel zmieniając w /etc/yum.repos.d/epel.repo enabled na 0, bo zacznie nam zastępować pakiety centosa tymi z epel.

 

Tworzymy plik /var/www/cgi-bin/php.fcgi

touch /var/www/cgi-bin/php.fcgi

 

Nadajemy mu atrybut wykonywalności

chmod +x /var/www/cgi-bin/php.fcgi

 

Wpisujemy zawartość pliku /var/www/cgi-bin/php.fcgi swoim ulubionym edytorem:

#!/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

 

6. Wpisujemy zawartość /etc/httpd/conf.d/fcgid.conf (zastępujemy)

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

 

7. Włączamy cache na dysku - dodajemy w httpd.conf takie wpisy:

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>.

 

8. Włączamy kompresję - dodajemy w httpd.conf

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

 

9. Upewnij się że w httpd.conf masz coś takiego:

<IfModule worker.c>                                                                                                                                                                    
StartServers         32                                                                                                                                                                
MaxClients         50                                                                                                                                                                  
MinSpareThreads     25                                                                                                                                                                 
MaxSpareThreads     75                                                                                                                                                                 
ThreadsPerChild     25                                                                                                                                                                 
MaxRequestsPerChild  0                                                                                                                                                                 
</IfModule>

 

Z wartościami można pokombinować w zależności od potrzeb.

 

10. Włączamy tryb worker zamiast prefork

service httpd stop
nano /etc/sysconfig/httpd

zdejmujemy hash z linii w pliku /etc/sysconfig/httpd:

HTTPD=/usr/sbin/httpd.worker

 

11. Uruchamiamy apache

service httpd start

 

12. O ile nic się nie zepsuło cieszymy się szybko działającym apachem :)

 

W przypadku problemów z selinuxem wpisujemy:

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

 

Teraz czas na wyniki testów:

Jak obiekt badania wybrałem stronę startową serwisu sugar crm, oraz kilka własnych skryptów, ale tutaj pokazuję wyniki akurat tego.

Dlaczego wybór padł na sugar crm ? Ponieważ:

- jest open source :)

- podczas uruchamiania strony głównej ładuje wiele swoich klas, tworzy obiekty itp, jeszcze lepiej wygląda to podczas uruchamiania podstron.

- jest straaaasznie powolny w domyślnej konfiguracji serwera.

- pokazuje na podstronach czas realizacji zapytania

 

Testowałem to poleceniem:

ab -n 1000 http://localhost/index.php

 

WYNIKI:

 

BEZ POPRAWEK:

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)

(z 1000 wywołań mógł sobie poradzić tylko serwer z dwoma prockami, na komputerze domowym miałem timeout)

 

 

Z WŁĄCZONYM eaccelerator:

Document Path:          /index.php
Document Length:        0 bytes

Concurrency Level:      1
Time taken for tests:   13.678317 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:    73.11 [#/sec] (mean)
Time per request:       13.678 [ms] (mean)
Time per request:       13.678 [ms] (mean, across all concurrent requests)
Transfer rate:          39.62 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:    12   13   8.1     13     262
Waiting:       12   12   8.1     12     262
Total:         12   13   8.1     13     262

Percentage of the requests served within a certain time (ms)
  50%     13
  66%     13
  75%     13
  80%     13
  90%     13
  95%     13
  98%     22
  99%     22
100%    262 (longest request)

 

Z WŁĄCZONYM CACHE:

Document Path:          /index.php
Document Length:        0 bytes

Concurrency Level:      1
Time taken for tests:   13.273106 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:    75.34 [#/sec] (mean)
Time per request:       13.273 [ms] (mean)
Time per request:       13.273 [ms] (mean, across all concurrent requests)
Transfer rate:          40.83 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:    12   13   0.1     13      15
Waiting:       10   12   1.0     13      15
Total:         12   13   0.1     13      15

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%     13
100%     15 (longest request)

 

TU EFEKTY WIDZIAŁEM TYLKO W PRZEGLĄDARCE (szybsze ładowanie stron, nie mierzyłem ale zauważalna różnica, choć równie dobrze może to być iluzja),

EDIT: Pewnie dlatego że kompresja itp były włączone przed testami o czym zapomniałem :), sorki, nie chce mi się robić drugi raz, wierzcie mi na słowo :)

 

 

No i na koniec po wszystkim z tutoriala

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)

 

Różnice przy końcowych zmianach już minimalne, ale przy większym obciążeniu będą lepiej widoczne

 

Dodatkowo im więcej mamy procesorów tym większy zysk z zamiany prefork na worker

 

Nie ma dokładnie zysku x10 ale chciałem nadać chwytliwy tytuł :)

 

 

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.

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 :)

 

Jeszcze nie skończyłem tak więc pewnie będę tu jeszcze coś dodawał :)

Edytowane przez qmic
code → codebox, bo Ci się strona z lekka rozjechała
Odnośnik do komentarza
Udostępnij na innych stronach

Takie fajne rzeczy mogłeś na wiki umieścić, rejestracja trwa chwilę, a składnia naprawdę jest banalna, wystarczy podejrzeć jakiś art :) Nie rozumiem, czemu ludzie wolą poradnik umieścić na forum niż na wiki.

 

Jak ktoś uzna że nadaje się na wiki to można tam umieścić.

Odnośnik do komentarza
Udostępnij na innych stronach

nadaje :)

 

A tak poważnie, w sieci jest pełno wtórnych, nikomu nie potrzebnych informacji (a co tam, napisze po raz n-ty o podstawach vi <_< ) jak jest coś choć trochę unikalnego, nie przeciętnego to warto to umieścić na wiki. Zamiast zastanawiać się czy treść "nadaje się na wiki" potraktuj to jak powiedział św. pamięci :ph34r: Arabski: "ja to traktuję jako notatnik, żeby rugi raz nie szukać" (albo jakoś tak to leciało :)). Zresztą kurcze, przecież po to ją mamy.

Odnośnik do komentarza
Udostępnij na innych stronach

No, qmic wykaż się. W sumie skopiowanie tekstu i lekkie "podrasowanie" pod wikipedię nie będzie Cię dużo kosztowało. Nie daj się prosić.

Wydaje mi się, że jak mamy wikipedię, to lepiej pisać takie poradniki tam właśnie zamiast podpinać na forum.

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
×
×
  • Dodaj nową pozycję...