Przejdź do profilu na Facebook.com

Instalacja i konfiguracja Blackfire.io

Instalacja i konfiguracja Blackfire.io

Ścieżka nawigacyjna

Instalacja i konfiguracja Blackfire.io

Treść główna

Krzysztof
Trzos
2018-05-05
Kategoria: Web developing

W ostatnim okresie czasu stworzyłem sobie za cel zapoznania się z narzędziem Blackfire.io. Udało mi się je w końcu rozgryźć, i tym doświadczeniem chciałbym się z Wami podzielić. Opiszę najpierw konfigurację środowiska deweloperskiego, a następnie jak rozpocząć z tym pracę.

Blackfire.io zostało stworzone z myślą tak zwanego "profilowania" skryptów i aplikacji internetowych napisanych w języku PHP. To znaczy, daje możliwość pozyskania danych na temat: jak długo podany kod się wykonuje, ile pobiera wszelkiego typu zasobów oraz jakie jego części w którym momencie i jak często się wywołują. Dzięki tym programista jest w stanie określić czy w jego aplikacji nie zachodzą jakieś niepożądane sytuacje, na przykład, zwalniające jakikolwiek proces. Jest to więc idealne narzędzie do optymalizacji w momencie, gdy żadnego innego tego typu nie mamy pod ręką (jak np. we frameworku Symfony).

Przechodząc jednak do rzeczy. Aby zacząć naszą nową przygodę, wymagane jest założenie konta na http://blackfire.io. Po dokonaniu tej czynności i poprawnym zalogowaniu, przejdźmy na podstronę "My Account" => "Settings" => "Credentials". Znajdziemy tam dane autoryzacyjne potrzebne podczas integracji z Blackfire. Mowa tutaj o:

  • Client ID;
  • Client Token;
  • Server ID;
  • Server Token.

Konfiguracja serwera

Do poprawnego funkcjonowania Blackfire.io na swoim serwerze potrzebujemy kilku rzeczy:

  • blackfire-agent
    Pakiet instalowany na maszynie. Nasłuchuje na odpowiednim sockecie i odbiera dane z profilowania, a następnie wysyła na odpowiedni serwer.
  • blackfire
    Kolejny pakiet. Jest to profiler, za pomocą którego dokonuje się analizy konkretnego skryptu lub strony www.
  • wtyczka do PHP (blackfire.so)
    Aby móc skomunikować serwer aplikacji z Blackfire, potrzebna będzie włączona odpowiednia wtyczka do PHP.

Wszystko powyższe może zostać zainstalowane na maszynie poprzez następującą komendę:

wget -O - https://packagecloud.io/gpg.key | apt-key add - \
    && echo "deb http://packages.blackfire.io/debian any main" | tee /etc/apt/sources.list.d/blackfire.list \
    && apt-get update \
    && apt-get install blackfire-agent \
    && version=$(php -r "echo PHP_MAJOR_VERSION.PHP_MINOR_VERSION;") \
    && curl -A "Docker" -o /tmp/blackfire-probe.tar.gz -D - -L -s https://blackfire.io/api/v1/releases/probe/php/linux/amd64/$version \
    && tar zxpf /tmp/blackfire-probe.tar.gz -C /tmp \
    && mv /tmp/blackfire-*.so $(php -r "echo ini_get('extension_dir');")/blackfire.so \
    && printf "extension=blackfire.so\nblackfire.agent_socket=tcp://127.0.0.1:8707\n" > /etc/php/5.6/cli/conf.d/blackfire.ini \
    && printf "extension=blackfire.so\nblackfire.agent_socket=tcp://127.0.0.1:8707\n" > /etc/php/5.6/fpm/conf.d/blackfire.ini

Uwaga!
Bardzo ważne w powyższym przykładzie jest odpowiednie ustawienie URL do socketa. W tym przypadku będzie to tcp://127.0.0.1:8707.

Kolejnym krokiem będzie ustawienie zmiennych środowiskowych, z których Blackfire będzie pobierać potrzebne mu dane konfiguracyjne.

BLACKFIRE_LOG_LEVEL="2"
BLACKFIRE_LOG_FILE="stderr"
BLACKFIRE_SOCKET="tcp://127.0.0.1:8707"

BLACKFIRE_CLIENT_ID="x"
BLACKFIRE_CLIENT_TOKEN="y"
BLACKFIRE_SERVER_ID="z"
BLACKFIRE_SERVER_TOKEN="q"

Oczywiście, tak dla przypomnienia, ustawianie ich w linuksie dokonujemy poprzez:

export ZMIENNA="wartość"

Ostatnim krokiem jest włączenie agenta od Blackfire. Wystarczy więc wywołać komendę blackfire agent, a naszym oczom powinien ukazać się następujący komunikat:

Agent listening on 127.0.0.1:8707

Swoją praktykę i eksperymenty z Blackfire opieram o kontener Dockera:

https://github.com/ktrzos/docker-blackfire

W powyższym repozytorium znajduje się pełna konfiguracja wraz z prostą aplikacją do profilowania pod adresem http://l.domain (nie zapomnijcie dodać domeny do /etc/hosts).

Aby uruchomić serwer, należy najpierw skopiować plik .env.dist jako .env i uzupełnić odpowiednie dane wspomniane w dziale "Konto blackfire.io". Następnie, z poziomu głównego katalogu repozytorium, wykonać komendę docker-compose up --build. Spowoduje to najpierw zbudowanie kontenera, a później jego uruchomienie. W czasie tej drugiej czynności, automatycznie włączany jest agent od Blackfire.io (dzięki pomocy supervisord).

Profilowanie

Mając już gotowy serwer, czas przejść do praktyki. Profilowania poprzez Blackfire.io można dokonać na dwa sposoby:

  1. poprzez komendę z poziomu konsoli;
  2. poprzez wtyczkę przeglądarki.

Profilowanie z poziomu konsoli

Pierwszym wspomnianym sposobem jest analiza aplikacji przez konsolę poprzez skrypt blackfire:

blackfire curl http://domain.com
blackfire run path/to/file.php

Wynikiem powinien być następujący komunikat w konsoli:

Profiling: [########################################] 10/10
Blackfire cURL completed
Graph URL https://blackfire.io/profiles/XXX/graph
No tests! Create some now https://blackfire.io/docs/cookbooks/tests
No recommendations

Wall Time 258µs
I/O Wait n/a
CPU Time n/a
Memory 1KB
Network n/a n/a n/a
SQL n/a n/a

Powyższy sposób jest najlepszy do profilowania programów niedostępnych z poziomu protokołu HTTP.

Profilowanie przez wtyczkę

Do Blackfire.io istnieje dość spora ilość integracji. W tym momencie interesują nas dwie z nich, czyli umożliwiających profilowanie poprzez przeglądarki:

Po zainstalowaniu odpowiedniej wtyczki, użytkownicy otrzymują dostęp do nowego okienka pop-up. W momencie kliknięcia w przycisk "Profile!", zostaje dokonany profiling aplikacji z aktualnie aktywnej zakładki. Często więc ten sposób analizy stron internetowych będzie o wiele wygodniejszy.

Pop-up wtyczki do przeglądarki integrującej się z Blackfire.io
Taki pop-up ukaże się w momencie kliknięcia w przycisk wtyczki od Blackfire.

Pasek narzędzi pokazujący się po dokonaniu profilowania.
Pasek narzędzi pokazujący się po dokonaniu profilowania.

Wynik profilowania

Każdy z wcześniej wspomnianych sposobów profilowania daje możliwość przejścia do odpowiedniego miejsca prezentującego wyniki. Domyślnym takim endpointem, możliwym w przyłości do zmiany na inny (np. zaimplementowany przez siebie), jest http://blackfire.io. Dlatego też to tutaj dane zostaną odpowiednio przeanalizowane i zaprezentowane.

W związku z czym, po profilowaniu użytkownik otrzyma adres URL, pod którym dostępna będzie wizualizacja wszystkich danych. Jeden z nich został już zaprezentowany w dziale "Profilowanie z poziomu konsoli" (XXX to unikalny ciąg znaków reprezentujący jeden zestaw statystyk):

https://blackfire.io/profiles/XXX/graph

Po wejściu na ten adres, ukaże się wynik profilowania podzielony na trzy sekcje:

  • Toolbar
    Podstawowe informacje o danym profilowaniu.
  • Diagram
    Diagram analizowanego kodu.
  • Lista użytych funkcji i metod
    Listę wykonanych podczas danego wywołania metod oraz funkcji wraz z powiązanymi z nimi informacjami.


Główna strona pojedynczego wyniku profilowania.
Główna strona pojedynczego wyniku profilowania.

Toolbar

Toolbar wyświetla podsumowane informacje związane z dokonanym profilowaniem. Można w nim znaleźć, między innymi:

  • czas wykonania się kodu;
  • ilość użytej pamięci;
  • ilość wykonanych zapytań SQL;
  • ilość wysłanych
  • zużycie procesora.

Jest też swojego rodzaju elementem nawigacyjnym. Zawiera odnośniki kierujące do odpowiednich działów z bardziej szczegółowymi danymi i statystykami.

Diagram

Sekcja przedstawiająca diagram wykonanego (podczas profilowania) kodu. Każdy węzeł jest reprezentacją jednej funkcji lub metody, i każdy z nich może mieć mniej lub bardziej kolorowe tło bądź brzegi. Intensywność koloru oznacza poziom ich aktywności, którego istnieją dwa rodzaje:

  • inclusive - aktywność węzła zawierająca w sobie aktywność węzłów podrzędnych (czyli uruchomionych przez ten pierwszodzędny węzeł);
  • exclusive - aktywność węzła bez wliczenia podrzędnych aktywności.

Przykład
Weźmy za przykład następującą klasę z dwiema metodami:

class Articles 
{
   // ...

    public function getArticleTitle(int $id) 
    {
        $article = $this->loadArticle($id);

        return $article->title;
    }

    private function loadArticle(int $id) 
    {
        $article = $this->db->load('Article', $id);
    }

    // ...
}

Załóżmy, że wykonanie funkcji getArticle() pochłonęło 10ms, a funkcji loadArticle() około 30ms. Oznacza to więc, że "exclusive time" dla tej pierwszej będzie wynosić 10ms, a "inclusive time" 40ms.

Sekcja z diagramem raportu z profilowania.
Sekcja z diagramem raportu z profilowania.

W diagramie te pierwsze aktywności wskazywane są poprzez grubsze obramowania. Drugie natomiast mają odpowiednio intensywniejsze kolory tła. Dodatkowo, węzły inclusive są węzłami należącymi do tak zwanych ścieżek "Hot Path" będących najbardziej aktywnymi wewnątrz aplikacji. W związku z czym, powinny być pierwszym miejscem do analizy pod względem optymalizacji aplikacji.

Lista funkcji i metod

Panel boczny z lewej strony jest równie ważny co wspomniane wcześniej sekcje. Spośród trzech dostępnych tam zakładek, skupię się na "Functions". Jak w przypadku diagramu, wyświetlana jest tu lista wszystkich funkcji oraz metod, których aktywność z wybranego działu wynosi co najmniej 1%. Dzięki niej użytkownik jest w stanie porównać które z nich są najbardziej czasochłonne lub pobierają najwięcej zasobów, co znacząco ułatwi znalezienie ewentualnie niepożądanych zachowań.

Notka
Jak zostało już wspomniane, w diagramie i zakładce "Functions" pokazywane są elementy, które stanowią więcej niż 1% całościowego wykonania się skryptu PHP. W związku z czym, niektóre partie kodu są w pierwszej kolejności ukryte. Powodem jest zwiększenie czytelności obu sekcji.

Zakładka z listą funkcji oraz metod.
Zakładka z listą funkcji oraz metod.

Każdy rekord tej listy zawiera następujący zestaw informacji:

  • nazwę funkcji lub metody;
  • aktywność exclusive;
  • aktywność inclusive;
  • ilość wywołań.

Jest to oczywiście tylko podstawowy zestaw informacji. Można dowiedzieć się o wiele więcej klikając na odpowiednią pozycję:

Szczegóły pojedynczej pozycji z listy funkcji oraz metod
Szczegóły pojedynczej pozycji z listy funkcji oraz metod.

Więcej informacji: Analyzing Call Graphs.

Podsumowanie

Przedstawiłem Wam podstawowy zakres narzędzia, jakim jest Blackfire.io. Ominąłem parę sekcji, aby artykuł nie był zbyt długi, co mam nadzieję, nie weźmiecie mi za złe. Jak widzicie, ilość prezentowanych informacji jest imponująca. Może zatem znacząco ułatwić pracę przy optymalizacji aplikacji jeśli nie ma się pod ręką profilera dostarczanego przez framework (jak np. w Symfony lub Laravel). Plusem jest możliwość korzystania z niego za darmo, ale niestety w obrębie aplikacji postawionych lokalnie, i z ograniczoną ilością uzyskiwanych informacji. Do podstawowej analizy powinno to każdemu wystarczyć. Jeśli jednak nie, cennik wygląda następująco (stan z dnia 2 maja 2018 r.):

  • Profiler - 19,90€ (za miesiąc przy płatności za cały rok)
    Pakiet umożliwia wyświetlanie dodatkowych informacji z przeprowadzonego profilowania.
  • Premium - 82,50€ (za miesiąc przy płatności za cały rok)
    Premium - 99,99€ (za miesiąc)
    Pakiet daje możliwość automatyzacji testów oraz rozszerzenia dostępu do grupy 3 użytkowników.

Jeśli zainteresowałem Was tematem, proponuję zapoznać się z dokumentacją. Znajdziecie tam parę przydatnych poradników oraz dokładniejszych opisów poszczególnych funkcjonalności. Zapraszam również do komentowania i wytykania mi błędów, jeśli takowe istnieją :). Ponadto, podzielcie się oczywiście swoimi doświadczeniami z Blackfire.

Niektóre z obrazów zaczerpnąłem ze strony http://blackfire.io.

Komentarze

Dodaj komentarz

loading...