Отслеживаем PHP с помощью PINBA на debian
PHP - исключительно популярный язык программирования, до сих пор огромное количество проектов пишется именно на нем. Язык ругают за отвратительный дизайн, неудобный синтаксис, кривое поведение в спорных случаях, отсутствие нормальных средств отладки - но его популярность это никак не снижает. Самое страшное для админа - ситуация, когда на сильно нагруженном проекте начинает тормозить код. Стандартные средства отладки (xprof, xdebug) роняют производительность языка в яму (накладные расходы - вплоть до пятикратного падения скорости), и как отлаживать сложный код на живую - совершенно неясно. Именно для борьбы с такими проблемами придумана PINBA - расширение для мониторинга скорости кода. Тут я расскажу, как установить PINBA (клиент, сервер и интерфейс) на debian и что с ними потом делать.
Как это работает
В отличае от XProf PINBA практически не замедляет работу скрипта. В базовом варианте она не требует никакой модификации PHP кода и никак на его выполнение не влияет. Устройство очень простое, штатно PINBA состоит из двух частей. Во-первых - это PHP extenstion (pinba.so), который отслеживает время выполнения скрипта (а так же - адрес скрипта и URL, нагрузку на CPU, память и код завершения). По окончании выполнения запроса он отправляет данные на сервер pinba. Сервер - это MySQL, собранный со специальным плагином (libpinba.so). Сервер принимает на определенном порту UDP-датаграммы и складывает их в базу. Интерфейсом для чтения статистики служит MySQL, что позволяет сравнительно легко анализировать данные и писать к ним свои интерфейсы. Важно, что php extension (генератор) не проверяет целостность отправленных данных или качество их доставки - он просто считает и отправляет.
Вот как будет выглядеть наша инсталляция:
Установка: клиент
В debian репозитории DotDeb есть нужный нам клиент (генератор статистики) и проще всего его прямо оттуда и поставить. Если у вас еще не установлен DotDeb - вот инструкция. После этого просто ставим пакет:
apt-get install -y php5-pinba
И настраиваем его, поправив файл /etc/php5/mods-available/pinba.ini
extension=pinba.so
pinba.enabled=1
pinba.server=172.16.10.10:30002
В этом примере предполагается, что сервер, собирающий статистику у нас имеет адрес 172.16.10.10 и порт 30002. После этого перезапускаем php и установка клиента на этом закончена.
Установка: сервер
С установкой сервера все несколько сложнее, так как пакет pinba-server есть только у dotdeb и он сломан. Его прийдется собирать из исходного кода. Для начала на сервер статистики поставим сам mysql. Это должен быть именно стандартный mysql, а не maria или percona:
apt-get install mysql-server-5.6 mysql-client-5.6 libmysqlclient18 libmysqlclient18-dev
Теперь поставим инструменты разработки, они потребуются нам, чтобы собрать пакет:
apt-get install build-essential protobuf-compiler libmysqlclient-dev \
libjudydebian1 libevent-dev libjudy-dev git libevent-2.0-5 libtool \
libevent-core-2.0-5 libevent-extra-2.0-5 libevent-openssl-2.0-5 \
libevent-pthreads-2.0-5 libprotobuf-dev libprotobuf-lite7 libprotobuf7 git-core
Переходим в tmp, выгружаем код pinba engine (сервер статистики) и исходный код mysql server:
cd /var/tmp
git clone 'https://github.com/tony2001/pinba_engine'
apt-get source mysql-server
Нам потребуется header-file от существующего mysql-сервера, скопируем. Я не знаю, какая версия mysql-server будет у вас, у меня это mysql-5.6-5.6.25.
cp '/usr/include/mysql/mysql_version.h' /var/tmp/mysql-5.6-5.6.25/include/
cp '/usr/include/mysql/my_config.h' /var/tmp/mysql-5.6-5.6.25/include/
Нам нужно узнать текущие опции сборки mysql:
OPTIONS="$(VISUAL=\"$(which 'cat')\" mysqlbug | grep 'Configured with' | sed -e 's/.*configure -v //')"
Соберем модуль:
cd pinba_engine
./buildconf.sh
./configure ${OPTIONS} \
--with-mysql='${MYSQL_SOURCES}' \
--with-judy \
--with-protobuf \
--with-event \
--libdir='/usr/lib/mysql/plugin/'
make
make install
Библиотека собрана, теперь можно установить плагин на сервер и создать базу, где мы будем хранить статистику:
mysql --execute="INSTALL PLUGIN pinba SONAME 'libpinba_engine.so';" --user=root
mysql --execute="CREATE DATABASE pinba DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci;" --user=root
mysql --user=root 'pinba' < '/tmp/pinba_engine/default_tables.sql'
mysql --user=root --execute="grant all on pinba.* to pinbauser@localhost identified by 'Hkx77jg8t6zGw6J5'"
Теперь сообщим серверу настройки pinba. Для этого поправим /etc/mysql/my.cnf. В секции [mysqld] добавим следующее:
pinba_port = 30002
pinba_address = 172.16.10.10
pinba_stats_gathering_period = 10000
pinba_stats_history = 900
pinba_temp_pool_size = 10000
pinba_request_pool_size = 10000
Чтобы изменения вступили в силу - надо перезапустить mysql. Разумеется, порт UDP/30002 не должен быть заблокирован в firewall. Настройка сервера на этом закончена, будемт ставить интерфейс.
Установка: интерфейс
Эту роль у нас будет выполнять Intaro’s pinboard. Интерфейс довольно простой, но удобный и симпатичный. В принципе, его можно поставить на любой сервер, с которого есть доступ к mysql, в моем примере это будет тот же сервер, куда мы собираем статистику. Для работы pinboard потребуется nginx, php5 (версии не менее 5.5) и php composer. Установим:
apt-get install -y php5-cli php5-common php5-curl php5-fpm php5-gd php5-mysql nginx-full
curl -sS https://getcomposer.org/installer | php
Выгрузим код:
cd /var/www
git clone git://github.com/intaro/pinboard.git --branch=v1.5.2
Установим зависимости:
cd pinboard
php composer.phar install
Чтобы интерфейс знал адрес и параметры соединения с базой, поправим настройки в файле ‘config/parameters.yml’:
db:
host: 127.0.0.1
name: pinba
user: pinbauser
pass: Hkx77jg8t6zGw6J5
остальное менять не нужно. Мигрируем базу:
./console migrations:migrate
Добавляем задание в крон для агрегации данных:
./console register-crontab
Теперь осталось настроить nginx. Для этого создадим файл /etc/nginx/sites-enabled/pinba со следующим содержанием:
server {
listen 80;
server_name pinba.ourdomian;
access_log /var/log/nginx/pinba.access.log;
error_log /var/log/nginx/pinba.error.log;
root /var/www/pinboard/web;
location = / {
try_files @site @site;
}
location / {
try_files $uri $uri/ @site;
}
location ~ \.php$ {
return 404;
}
location @site {
fastcgi_pass unix:///var/run/php5-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
}
location ~ /\.(ht|svn|git) {
deny all;
}
}
Теперь достаточно просто перезапустить nginx и можно пользоваться нашим новым интерфейсом. Важно понимать, что статистика агрегируется раз в N минут (частоту спросит сам pinboard при миграции данных), но данные в секции live доступны в любой момент.