Wednesday
7
April
autor:
Mateusz Tymek
kategorie:

Wydajność Zend Framework - cz. 1

Wiele osób sądzi że Zend Framework jest jednym z najmniej wydajnych rozwiązań tego typu.Tworząc aplikację bazującą na frameworku szybko zauważymy, że działa ona dużo wolniej niż odpowiednik napisany w czystym PHP. Czy powinniśmy się tym przejmować?
Im bardziej rozbudowany projekt, tym proporcjonalnie mniejszy narzut wynikający z zastosowania biblioteki. W większych aplikacjach problemem nie jest framework, lecz (najczęściej) baza danych.

Mimo tego, warto wiedzieć co ma wpływ na tak niską wydajność. A także to, że niewielkim kosztem można ją poprawić.
Dzisiejszy wpis to pierwsza część krótkiej serii artykułów o wydajności frameworku. Zaczniemy od podstaw - pokażę kilka sposobów na pomiar prędkości.

Podstawowe informacje

Najpierw dobrze byłoby wiedzieć w jakim czasie generuje się dana strona. Dodajemy jedną linijkę na początku pliku index.php:

$startTime = microtime(true);
Oraz kilka na końcu:

$time = round(microtime(true) - $startTime, 4);
$memory = round(memory_get_peak_usage(true) / 1024);
$files = count(get_included_files());
echo <<<EOS
<small style="position: fixed; right: 0; bottom: 0; background-color: #dedede; padding: 4px">
    Czas generowania strony: {$time}s <br />
    Pamięć: {$memory} kB <br />
    Dołączone pliki: {$files}
</small>
EOS;

Teraz przy każdym odświeżeniu strony zobaczymy trzy podstawowe, związane z wydajnością parametry.
To rozwiązanie jest dosyć prymitywne i ma pewne ograniczenia (np może psuć wyjście gdy generujemy XML w żądaniach AJAX), jednak ma też swoje zalety. Znacznie więcej informacji pokaże nam ZFDebug - jest to belka informacyjna, wzorowana na swoim odpowiedniku z projektu Symfony. Pod tym adresem można znaleźć więcej informacji na ten temat.

Profilowanie

Aby dowiedzieć się czym dokładnie zajmuje się interpreter, możemy sięgnąć po narzędzie profilujące - Xdebug. Zależnie od ustawionych opcji profilowanie może odbywać się za każdym razem gdy wczytywana jest strona lub (moim zdaniem bardziej praktyczny sposób) - na życzenie, po podaniu parametru XDEBUG_PROFILE w pasku adresu.

Jak skorzystać z profilera?

  • instalujemy rozszerzenie xdebug;
  • dodajemy wpis xdebug.profiler_enable_trigger = 1 do pliku php.ini;
  • restartujemy Apache (jeżeli php pracuje jako moduł tego serwera).

Teraz możemy zabrać się do profilowania. Wpisujemy w przeglądarce:

http://localhost/moja_strona/?XDEBUG_PROFILE

Strona zostanie wygenerowana, a odpowiednie informacje będą umieszczone w katalogu tymczasowym.
Dobrym narzędziem do prezentowania wyników jest Webgrind. Wystarczy go ściągnąć, wgrać do katalogu serwowanego przez Apache i uruchomić w przeglądarce. Po naciśnięciu przycisku "update" wygenerowany zostanie raport z ostatniej sesji profilera:

Webgrind to bardzo praktyczne narzędzie prezentujące wyniki profilowania

W każdym wierszu widać nazwę wywoływanej metody, całkowitą liczbę wywołań i czas wykonywania (najpierw samej metody, potem wraz z funkcjami które sama wywołała). Kliknięcie na nazwę dostarczy jeszcze więcej informacji.

Apache Benchmark

Wreszcie, mając podstawowe informacje, możemy sprawdzić jak strona zachowuje się pod większym obciążeniem. Odpowiedni program to Apache Benchmark. Wykonuje on określoną liczbę zapytań do serwera, które dodatkowo mogą być przeprowadzane jednocześnie.
Mimo swojej nazwy nadaje się także do testowania stron działających pod innymi serwerami (chociażby nginx).

Oto przykładowy wynik działania programu ab:

mateusz@linux-v65i:~> /usr/sbin/ab2 -n 100 -c5 http://domena.com/moja-strona/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient).....done

Server Software:        Apache/2.2.13
Server Hostname:        domena.com
Server Port:            80

Document Path:          /moja-strona/
Document Length:        25480 bytes

Concurrency Level:      5
Time taken for tests:   31.902 seconds
Complete requests:      100
Failed requests:        11
   (Connect: 0, Receive: 0, Length: 11, Exceptions: 0)
Write errors:           0
Total transferred:      2584189 bytes
HTML transferred:       2547989 bytes
Requests per second:    3.13 [#/sec] (mean)
Time per request:       1595.123 [ms] (mean)
Time per request:       319.025 [ms] (mean, across all concurrent requests)
Transfer rate:          79.10 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    3  16.9      0     124
Processing:   865 1575 211.4   1577    2002
Waiting:      847 1518 198.8   1511    1920
Total:        865 1578 214.9   1577    2018

Percentage of the requests served within a certain time (ms)
  50%   1577
  66%   1659
  75%   1737
  80%   1767
  90%   1855
  95%   1948
  98%   2002
  99%   2018
 100%   2018 (longest request)

Ilość zwróconych informacji jest dosyć duża. Zwróćmy uwagę na "Requests per seconds" - pokazuje on ile tak naprawdę "wytrzyma" nasza aplikacja.

Tyle na początek. W następnym artykule z tej serii postaram się odpowiedzieć na pytanie co dokładnie wpływa na prędkość działania frameworka.

Tagi: apache benchmark, wydajność
Saturday
26
June
autor:
Mateusz Tymek
kategoria:
brak komentarzy skomentuj

"Resetujący" CSS i Firebug

Firebug

Używanie "resetującego" arkusza CSS jest dosyć dobrą metodą na uzyskanie identycznego wyglądu we wszystkich przeglądarkach. Niestety, znacznie utrudnia badanie styli przy pomocy Firebuga - w widoku CSS resetujące reguły powtarzają się kilkakrotnie, skutecznie zaciemniając obraz całości.

Spróbuj "zbadać" któryś z odnośników w tym blogu - w zakładce CSS zobaczysz coś takiego:

Usunięcie reguł z pliku reset.css jest proste, jednak wymaga grzebania w kodzie Firebuga - nie da się tego wyklikać.

czytaj dalej »

Tagi: firebug
Sunday
13
June
autor:
Mateusz Tymek
kategoria:

Migracja z Apache do Nginx

Serwer na którym postawiony jest ten blog to "słaby" dedyk z oferty OVH, z zainstalowanym Debianem. Aktualnie obsługuje kilkanaście stron z dość małym natężeniem ruchu (głównie proste, statyczne wizytówki). Całość śmiga na serwerze Apache i mod_php. Ostatnio, spodziewając się zwiększonego ruchu na jednej z tych stron, postanowiłem zwiększyć wydajność poprzez instalację serwera WWW Nginx.

czytaj dalej »

Tagi: nginx, apache, dedyk, fastcgi, php
Wednesday
19
May
autor:
Mateusz Tymek
kategorie:

Przykład zastosowania Zend_Auth i Zend_Acl - cz. 2

W poprzednim wpisie pokazałem jak można zastosować Zend_Auth do obsługi uwierzytelniania. Dzisiaj przykładowa aplikacja zostanie wzbogacona o kontrolę dostępu użytkowników, zrealizowaną z wykorzystaniem Zend_Acl.

czytaj dalej »

Tagi: autoryzacja, zend_acl, zend_tool
Sunday
16
May
autor:
Mateusz Tymek
kategorie:

Przykład zastosowania Zend_Auth i Zend_Acl - cz. 1

Uwierzytelnianie i autoryzacja w Zend Framework: Zend_Auth i Zend_AclW artykule przedstawię "przepis" na zbudowanie prostej aplikacji wykorzystującej Zend_Auth do logowania, oraz - w drugiej części - Zend_Acl do kontroli dostępu użytkowników.

czytaj dalej »

Tagi: zend_auth, zend_form, zend_tool, zend_acl, uwierzytelnianie
Wednesday
17
February
autor:
Mateusz Tymek
kategorie:

Zend_Mail: wysyłanie poczty w Zend Framework

Zend_Mail: wysyłanie poczty z załącznikami w Zend Framework

Wysyłanie poczty w czystym PHP nigdy nie należało do przyjemności. Funkcja mail() może i sprawdza się gdy chcemy wysłać krótką wiadomość tekstową do jednego odbiorcy, jednak zawodzi w bardziej skomplikowanych zastosowaniach. Wyobraźmy sobie wysyłanie listu z dołączonym plikiem PDF i kilkoma obrazkami wplecionymi w treść. Bez jakiejś dodatkowej biblioteki musielibyśmy utworzyć całą wiadomość ręcznie (przykład). Na szczęście programiści Zenda przygotowali dosyć dobrą klasę którą możemy łatwo wykorzystać w naszej aplikacji: Zend_Mail. W tym tekście pokażę przykłady zastosowania tej klasy. Oprócz tego, zaprezentuję prosty sposób na testowanie wysyłania wiadomości przy pomocy własnego transportu.

czytaj dalej »

Tagi: poczta elektoniczna, zend_mail
Więcej artykułów