Wyszukiwanie w witrynie

5 wskazówek, jak zwiększyć wydajność serwera WWW Apache


Według niedawnego raportu Netcraft (znanej firmy internetowej, która dostarcza między innymi statystyki użytkowania przeglądarki internetowej), Apache w dalszym ciągu jest najczęściej używanym serwerem WWW wśród witryn i komputerów podłączonych do Internetu.

Ponadto wśród najlepszych serwerów internetowych największy wzrost odnotowuje Apache, a za nimi plasują się Nginx i IIS. Zatem jeśli jesteś administratorem systemu odpowiedzialnym za zarządzanie instalacjami Apache, musisz wiedzieć, jak upewnić się, że Twój serwer WWW działa najlepiej jak potrafi, zgodnie z potrzebami Twoimi (lub potrzebami Twojego klienta).

W tym artykule omówimy kilka wskazówek, które pomogą Ci upewnić się, że Apache będzie działał płynnie i będzie w stanie obsłużyć liczbę żądań, których oczekujesz od zdalnych klientów.

Należy jednak pamiętać, że Apache nie został zaprojektowany z myślą o ustanawianiu rekordów testów porównawczych – ale mimo to nadal jest w stanie zapewnić wysoką wydajność w niemal każdym przypadku użycia, jaki możesz sobie wyobrazić.

WSKAZÓWKA nr 1: Zawsze aktualizuj Apache do najnowszej wersji

Jest rzeczą oczywistą, że zainstalowanie najnowszej wersji Apache jest prawdopodobnie jedną z pierwszych rzeczy, które należy wziąć pod uwagę. Na dzień 19 listopada 2015 najnowsza wersja Apache dostępna w repozytoriach CentOS 7 to 2.4.6, natomiast w Debianie jest to >2.4.10.

Jednakże do nowo wydanej stabilnej wersji, która następnie jest udostępniana do pobrania i zainstalowania ze źródła, mogło zostać dodane niedawne ulepszenie lub poprawka błędu. Znajdują się tu również instrukcje kompilacji i instalacji – pamiętaj tylko, że jeśli wybierzesz tę metodę aktualizacji, możesz na wszelki wypadek wykonać kopię zapasową bieżących plików konfiguracyjnych/witryn/hostów wirtualnych.

W każdym razie możesz sprawdzić aktualnie zainstalowaną wersję w następujący sposób:

httpd -v               [On RedHat/CentOS based systems]
apache2 –v             [On Debian/Ubuntu based systems] 

Ogólnie rzecz biorąc, trzymaj się metody aktualizacji dostarczonej przez menedżera pakietów wybranej dystrybucji (yum update httpd lub aptitude Safe-upgrade Apache2, dla CentOS lub Debiana, odpowiednio), chyba że nie ma innego sposobu. Informacje o najnowszym wydaniu można przeczytać w sekcji Dokumentacja Apache w witrynie projektu serwera HTTP Apache.

WSKAZÓWKA nr 2: Jeśli używasz jądra starszego niż 2.4, rozważ aktualizację już teraz

Dlaczego? Wersje jądra 2.4 i nowsze mają domyślnie włączone wywołanie systemowe jądra sendfile. To z kolei ułatwia wysokowydajne przesyłanie plików sieciowych (co jest pożądane w kontekście komunikacji serwer WWW-klient) i umożliwia Apache szybsze dostarczanie treści statycznych przy mniejszym obciążeniu procesora poprzez jednoczesne wykonywanie operacji odczytu i wysyłania.

Możesz wyświetlić aktualnie zainstalowane jądro za pomocą:

uname -r

i porównaj je z najnowszym stabilnym jądrem na www.kernel.org (4.3 w chwili pisania tego tekstu).

Chociaż nie jest to proces przeznaczony dla początkujących, aktualizacja jądra jest interesującym ćwiczeniem pozwalającym dowiedzieć się więcej o wewnętrznych elementach Linuksa.

WSKAZÓWKA nr 3: Wybierz moduł wieloprocesorowy (MPM), który najlepiej sprawdzi się w Twoim przypadku

W praktyce MPM rozszerzają modułową funkcjonalność Apache, pozwalając ci zdecydować, jak skonfigurować serwer WWW tak, aby łączył się z portami sieciowymi na komputerze, akceptował żądania od klientów i korzystał z procesów potomnych (i wątków, alternatywnie) w celu obsługi takich żądań.

Począwszy od wersji 2.4 Apache oferuje trzy różne MPM do wyboru, w zależności od potrzeb:

  1. MPM prefork wykorzystuje wiele procesów potomnych bez wątków. Każdy proces obsługuje jedno połączenie na raz, bez tworzenia oddzielnych wątków dla każdego z nich. Bez wchodzenia w szczegóły, możemy powiedzieć, że będziesz chciał używać tego MPM tylko podczas debugowania aplikacji, która używa lub jeśli twoja aplikacja musi sobie radzić z modułami, które nie są bezpieczne dla wątków, takimi jak mod_php.
  2. worker MPM wykorzystuje kilka wątków na procesy potomne, przy czym każdy wątek obsługuje jedno połączenie na raz. Jest to dobry wybór w przypadku serwerów o dużym natężeniu ruchu, ponieważ umożliwia obsługę większej liczby jednoczesnych połączeń przy mniejszej ilości pamięci RAM niż w poprzednim przypadku.
  3. Wreszcie, event MPM jest domyślnym MPM w większości instalacji Apache w wersji 2.4 i nowszych. Jest podobny do roboczego MPM w tym sensie, że tworzy wiele wątków na proces potomny, ale ma tę zaletę: powoduje połączenia KeepAlive lub bezczynne (podczas gdy pozostają one w tym stanie) być obsługiwane przez pojedynczy wątek, uwalniając w ten sposób pamięć, którą można przydzielić innym wątkom. Ten MPM nie nadaje się do użytku z modułami, które nie są bezpieczne dla wątków, takimi jak mod_php, dla których zamiast tego należy użyć zamiennika, takiego jak PHP-FPM.

Aby sprawdzić MPM używany przez instalację Apache, możesz:

httpd -V

Poniższy obraz pokazuje, że ten konkretny serwer internetowy korzysta z prefork MPM.

Aby to zmienić, musisz edytować:

/etc/httpd/conf.modules.d/00-mpm.conf          [On RedHat/CentOS based systems]
/etc/apache2/mods-available/<mpm>.load   [On Debian/Ubuntu based systems]

Gdzie może oznaczać mpm_event, mpm_worker lub mpm_prefork.

i odkomentuj linię ładującą żądany moduł w następujący sposób:

LoadModule mpm_event_module modules/mod_mpm_event.so

Uwaga: aby zdarzenie MPM działało w Debianie, może być konieczne zainstalowanie pakietu libapache2-mod-fastcgi z niewolnego repozytoria.

Dodatkowo dla CentOS będziesz potrzebować php-fpm (wraz z fcgi i mod_fcgid), podczas gdy w Debianie nazywa się to php5-fpm< (wraz z apache2-mpm-event).

Na koniec zrestartuj serwer WWW i nowo zainstalowaną usługę php-fpm (lub php5-fpm):

W systemie RedHat/CentOS

systemctl restart httpd php-fpm && systemctl enable httpd php-fpm

Na Debianie/Ubuntu

systemctl restart apache2 php5-fpm && systemctl enable apache2 php5-fpm

Chociaż możesz ustawić Apache tak, aby używał określonego MPM, tę konfigurację można zastąpić dla każdego hosta wirtualnego w taki sam sposób, jak wskazano wcześniej.

Po prostu upuść odpowiednie tagi w pliku konfiguracyjnym każdego wirtualnego hosta i gotowe – ale upewnij się, że używasz jednego i tylko jednego MPM na vhost.

Na koniec pamiętaj, że niezależnie od wybranej dystrybucji, php-fpm opiera się na implementacji FastCGI, dlatego wcześniej zalecałem instalację dodatkowych pakietów.

Więcej szczegółów i przykładów na temat php-fpm oraz tego, jak może wraz ze zdarzeniem MPM zwiększyć wydajność Apache, należy zapoznać się z oficjalną dokumentacją.

Oto co widzę po zmianie domyślnego MPM z prefork na event w tym samym okienku pokazanym na poprzednim obrazku:

W CentOS 7 musisz się upewnić, że usługi http i https są włączone przez zaporę sieciową i że interfejs(y) sieciowy ) są prawidłowo dodawane do strefy domyślnej.

Na przykład:

firewall-cmd --zone=internal --add-interface=tun6to4 
firewall-cmd --zone=internal --add-interface=tun6to4 --permanent 
firewall-cmd --set-default-zone=internal 
firewall-cmd --add-service=http 
firewall-cmd --add-service=https 
firewall-cmd --add-service=http --permanent 
firewall-cmd --add-service=https --permanent 
firewall-cmd --reload

Poruszam ten temat, ponieważ niedawno doświadczyłem problemu, w którym domyślne ustawienia konfiguracji zapory ogniowej w chmurze VPS uniemożliwiały php-fpm i Apache przetwarzanie plików php.

Jako podstawowy test (jestem pewien, że możesz pomyśleć o bardziej skomplikowanych lub stresujących testach) utworzę plik php, który sprawdzi istnienie innego pliku o nazwie test.php w tym samym katalogu dwóch CentOS 7 serwerów o tej samej charakterystyce sprzętowej i obciążeniu, ale z różnymi MPM. Jeden z nich użyje zdarzenia, a drugi użyje preforka:

To jest kod php, który zapisałem w pliku o nazwie checkiffileexists.php:

<?php
$filename = 'test.php';

if (file_exists($filename)) {
    echo "The file $filename exists";
} else {
    echo "The file $filename does not exist";
}
?>

Następnie uruchomimy narzędzie porównawcze Apache (ab) z 200 jednoczesnymi żądaniami, aż do zakończenia 2000 żądań:

ab -k -c 100 -n 2000 localhost/checkiffileexists.php

Przeprowadźmy test i porównajmy wyniki. Zwróć uwagę na statystyki wydajności:

Jak widać, wydajność serwera ze zdarzeniem jest znacznie lepsza od jego odpowiednika prefork w każdym aspekcie tego testu.

WSKAZÓWKA nr 4: Rozsądnie przydzielaj pamięć RAM dla Apache

Być może najważniejszym elementem sprzętu, który należy wziąć pod uwagę, jest ilość RAM przydzielona dla każdego procesu Apache. Chociaż nie możesz tego bezpośrednio kontrolować, możesz ograniczyć liczbę procesów potomnych za pomocą dyrektywy MaxRequestWorkers (wcześniej znanej jako MaxClients w Apache 2.2), co ograniczy wykorzystanie pamięci RAM przez Apache. Ponownie możesz ustawić tę wartość dla każdego hosta lub hosta wirtualnego.

Aby to zrobić, należy zanotować średnią ilość pamięci RAM wykorzystywaną przez Apache, a następnie pomnożyć ją przez liczbę MaxRequestWorkers, a otrzymamy ilość pamięci, która zostanie przydzielona na procesy Apache. Jedną z rzeczy, których nigdy nie chcesz, aby Twój serwer WWW zrobił, jest rozpoczęcie korzystania z wymiany, ponieważ znacznie obniży to jego wydajność. Dlatego też powinieneś zawsze utrzymywać wykorzystanie pamięci RAM przez Apache w granicach, na jakie Cię stać i nigdy nie polegać na wymianie.

Na przykład poniższy blok ograniczy liczbę jednoczesnych klientów do 30. Jeśli więcej klientów trafi na hosta, mogą doświadczyć opóźnienia lub chwilowej awarii, którą można łatwo rozwiązać, odświeżając przeglądarkę. Chociaż można to uznać za niepożądane, jest to zdrowsze dla serwera, a na dłuższą metę najlepsze także dla Twojej witryny.

Możesz umieścić ten blok wewnątrz /etc/httpd/conf/httpd.conf lub /etc/apache2/apache2.conf, w zależności od tego, czy używasz CentOS, czy Debiana.

Pamiętaj, że ta sama zasada dotyczy wszystkich MPM – używam tutaj zdarzenia, aby kontynuować koncepcję opisaną w poprzedniej wskazówce:

<IfModule mpm_event_module>
    StartServers 3
    MinSpareThreads          25
    MaxSpareThreads          75
    ThreadLimit                      64
    ThreadsPerChild          25
    MaxRequestWorkers    30
    MaxConnectionsPerChild    1000
</IfModule>

W każdym razie zdecydowanie zaleca się zapoznanie się z dokumentacją Apache 2.4, aby sprawdzić, które dyrektywy są dozwolone dla wybranego MPM.

WSKAZÓWKA #5: Poznaj swoje zastosowania

Ogólna zasada jest taka, że nie powinieneś ładować żadnych modułów Apache, które nie są absolutnie potrzebne do działania aplikacji. Będzie to wymagało przynajmniej ogólnej wiedzy na temat aplikacji działających na Twoim serwerze, szczególnie jeśli jesteś administratorem systemu i za rozwój odpowiedzialny jest inny zespół.

Możesz wyświetlić listę aktualnie załadowanych modułów za pomocą:

httpd -M          [On RedHat/CentOS based systems]
apache2ctl -M     [On Debian/Ubuntu based systems]

Aby zwolnić/wyłączyć moduły w CentOS, będziesz musiał zakomentować linię zaczynającą się od LoadModule (albo w głównym pliku konfiguracyjnym, albo w pomocniczym pliku wewnątrz /etc/httpd/conf.modules.d.

Z drugiej strony Debian udostępnia narzędzie o nazwie a2dismod do wyłączania modułów i jest używane w następujący sposób:

a2dismod module_name

Aby ponownie włączyć tę funkcję:

a2enmod module_name

W obu przypadkach pamiętaj o ponownym uruchomieniu Apache, aby zmiany zaczęły obowiązywać.

Podsumowanie

W tym artykule omówiliśmy 5 wskazówek, które pomogą Ci dostroić serwer WWW Apache i zwiększyć jego wydajność. Ponadto powinieneś pamiętać, że optymalizacja i wydajność bez zabezpieczeń nie ma sensu, więc możesz zapoznać się z instalacją mod_pagespeed w celu poprawy wydajności serwera WWW oraz artykułem ze wskazówkami dotyczącymi hartowania Apache na linux-console.net.

Ponieważ nie możemy odpowiednio omówić wszystkich aspektów tego tematu w tym artykule, być może przyjdzie Ci do głowy inny pomysł, którym chciałbyś podzielić się z resztą społeczności. Jeśli tak, daj nam znać, korzystając z poniższego formularza komentarza.