Установка PHP 7 (для php-fpm) с помощью phpbrew + бенчмарки php 7

php-brewВсем привет. Это я, Netandreus и сейчас мы попробуем накатить свежий php 7 параллельно с текущей веткой. И не просто накатить, а сделать это с помощью phpbrew. Эта утилита пришла к нам из мира ruby, где rvm уже давно радует разработчиков и админов. С ней поддерживать разные версии интерпретатора значительно лучше, чем…. чем без неё.

dve_kiski_2

Задача

Поставить с помощью phpbrew php7-fpm параллельно с php5-fpm на одной системе и разрулить их по разным портам машины.

Устанавливаем phpbrew и зависимости

Для начала надо установить всё, что нам может понадобиться при компиляции php.

Теперь ставим сам phpbrew.
Я создавал отдельного пользователя phpbrew с домашним каталогом /opt/phpbrew и ставил всё туда.

Добавлям эти строки в /home/phpbrew/.bashrc

Ставим его.

Этой командой можно посмотреть, какие версии php доступны для установки.

phpbeew-known

А с помощью этой команды можно посмотреть опции конфигурирования.

Качаем, конфигурируем и компилируем php 7

Логи смотрим из другого окна терминала с помощью

Там же можно подчерпнуть пути, куда наш phpbrew раскидал файлы.

Делаем файл www.conf

– меняем там юзера и группу на www-data. У меня это юзер от которого работает php и nginx.
– меняем порт на 9030, чтобы не пересекаться с существующим php5-fpm

Включаем Zend Opcode Cache

Опкод-кэшер теперь включен в ядро php, но выключен по умолчанию. Чтобы включить его добавляем следующие строки в php.ini в секцию [opcache]. PHP должен быть собран с параметром –enable-opcache

Вот, что должно получиться.

zend_opcache

Файл /usr/local/lib/php7-fpm-checkconf

Создаем файл php7-fpm-checkconfdisk-save

и пишем туда следующее:

При скачки с моего сайте не забываете убирать символы (^M).

Ставим атрибут на выполнение:
sudo chmod +x /usr/local/lib/php7-fpm-checkconf

Файл /etc/init.d/php7-fpm

Можете качнуть файл с моего сервера (удалив потом ^M или \r символы перевода строки) с помощью скрипта

или вручную:

Создаём файл /etc/init.d/php7-fpmdisk-save
Ставим атрибут на выполнение:
chmod +x /etc/init.d/php7-fpm

Шапка у него будет вот такая:

Обратите внимание, что в разделе “Provides” должно быть только “php7-fpm”, а не “php5-fpm”, чтобы не пересечься с основной версией.

Создаём симлинк и перечитываем сервисы

Файл /lib/systemd/system/php7-fpm.service

 Создаём файл disk-save/lib/systemd/system/php7-fpm.service со следующим содержанием:

При скачивании с сайта не забываем делать так:

Далее перезагружаем его.

В файле конфига /home/phpbrew/.phpbrew/php/php-7.0.4/etc/php-fpm.conf меняем значение параметра pid

чтобы оно совпадало с тем, тчо написано в init.d скрипте

Всё, теперь пробуем запустить новый сервис и посмотреть его в процессах.

Установка legacy MYSQL extension в php 7

После перехода на новый php7 у ваших сайтов может отвалиться база данных. Это связано с тем, что из php7 полностью удалили поддержку старых функций mysql_*. Так что либо вы переписываете ваш php-код для использования mysqli/pdo, либо ставите старое mysql расширение для php. Как это сделать – см. ниже.

Смотрим вывод, что всё поставилось, как надо.

Перезагружаем.

Смотрим, что новое старое расширение появилось в выводе phpinfo().
php7-legacy-mysql-extension

Установка gd extension на php 7

Установка php-7 совместимого memcached extension

sudo apt-get install libmemcached-dev

phpbrew ext install https://github.com/php-memcached-dev/php-memcached php7 — –disable-memcached-sasl –with-php-config=/opt/phpbrew/.phpbrew/php/php-7.0.4/bin/php-config

Установка phpMyAdmin на PHP 7

Далее в файле config.inc.php меняем значение хоста с localhost на 127.0.0.1

Установка php 5.2.17 через phpbrew

Попробуем поставить старую версию через phpbrew.

Подключаем php-5.2.17-cgi через spawn-fcgi к nginx

А теперь займемся подключением. Мы понимаем, что наш бинарник php-cgi лежит вот здесь:

Дальше нам надо настроить спаунер для nginx (аналогично предыдущей статье).

Nginx будет смотреть заголовок host (server_name) и проксировать запрос либо на php5.2 в режиме fcgi – port 9020, либо на новый php_fpm (основной) – port 9010.
Для этого сделаем вторую обертку для nginx.

Делаем саму обертку.

mcedit /opt/phpbrew/php5.2.17.fcgi

Теперь делаем файл службы.

sudo mcedit /etc/init.d/php5.2.17-fpm

Скачать можно тут. А то на страничке пробелы похерятся.

Ставим бит исполнения и проверяем нашу новую службу.

Должны работать сразу и php-fpm и древний php52 через fcgi.

Смотрим процессы – новая служба должна убиться. Этим мы проверим корректность работы с pid-файлом.

triple-php
Отлично, теперь можно добавить её в систему.

Файл /lib/systemd/system/php5.2.17-fpm.service

 Создаём файл disk-save/lib/systemd/system/php5.2.17-fpm.service со следующим содержанием:

Далее перезагружаем его.

Теперь осталось добавить vhost для nginx с новой службой.

Бенчмарки php 7

Тестовый стенд – виртуалка Ubuntu 14.04 LTS, 2 vCPU 4096Mb RAM, 60Gb disk, nginx-1.9.3, актуальная версия WordPress 4.4.2

В тестировании менялся только интерпретатор php. Участники: php5.2.17, php5,6, php7.0.4 Запрашивалась главная страница. Какое-либо кэширование и оптимизационные фиксы в  WordPress были отключены. Плагины выключены, а базе несколько страниц и записей. Вообщем just-another-blog тест. Анализировались два параметра: время исполнения 50% запросов, и количество запросов в секунду. Инструмент тестирования: apache benchmark. Параметры нагрузки: c – кол-во одновременных запросов, n – общее количество запросов теста. PHP7 для связи с БД использовал legacy-extension. Тест выполнялся локально, чтобы исключить сетевые задержки. В таблице ниже указаны конкретные версии компонентов php.

Versions PHP Zend Engine Zend Opcache
PHP5.2 5.2.17 2.2.0
PHP5.6 5.6.11 2.6.0 7.0.6-dev
PHP7 7.0.4 3.0.0 7.0.6-dev

Ну а вот результаты.

Time per request 50% (ms). Чем меньше – тем лучше.

 

c=10,n=100 c=20,n=100 c=50,n=100 c=10,n=1000 c=20,n=1000 c=50,n=1000
PHP5.2 1210 2165 5607 1190 2413 6055
PHP5.6 340 670 1678 343 676 1683
PHP7 168 322 793 165 328 812

 

bench-time-per-request

 

 

Requests per second (rps). Чем больше – тем лучше.

 

c=10,n=100 c=20,n=100 c=50,n=100 c=10,n=1000 c=20,n=1000 c=50,n=1000
PHP5.2 8,19 8,48 8,32 8,43 8,41 8,28
PHP5.6 28,87 29,56 29,18 29,13 29,6 29,74
PHP7 59,44 61,19 60,45 60,62 60,86 61,29

bench-rps

На диаграммах мы видим, что переход на PHP7 с PHP 5.6 даёт двукратный(!) прирост производительности WordPress блога.

Invision Power Board и PHP 7

Чтобы IPB корректно работал надо сделать небольшие фиксы.

В файле conf_global.php меняем эту строчку

$INFO[‘sql_host’] = ‘localhost’;

на эту:

$INFO[‘sql_host’] = ‘127.0.0.1’;

В файле /cache/skin_cache/cacheid_1/skin_global.php заменить эту строчку:

$_ips___x_retval .= ”
” . (($data[‘share_enabled’]) ? (“” . (($data[‘customOutput’] and is_array( $data[‘customOutput’] )) ? (”
” . $this->registry->output->getTemplate($data[‘customOutput’][0])->$data[‘customOutput’][1]( $data[‘_rawUrl’], $title, $data[‘customOutput’][2] ) . ”
“) : (“<li><a href=\”” . $this->registry->getClass(‘output’)->formatUrl( $this->registry->getClass(‘output’)->buildUrl( “sharelink={$data[‘share_key’]};{$data[‘_url’]};{$title}”, “public”,” ), “”, “” ) . “” . (($data[‘overrideApp’]) ? (“&amp;overrideApp={$data[‘overrideApp’]}”) : (“”)) . “\” rel=\”nofollow\” target=\”_blank\” title=\”” . ((isset( $this->lang->words[‘gbl_sharelink_with_’ . $data[‘share_key’] ] )) ? (“{$this->lang->words[‘gbl_sharelink_with_’ . $data[‘share_key’] ]}”) : (“{$this->lang->words[‘gbl_sharelink_with’]} {$data[‘share_title’]}”)) . “\” class=’_slink’ id=’slink_{$data[‘share_key’]}’><img src=\”{$this->settings[‘public_cdn_url’]}style_extra/sharelinks/{$data[‘share_key’]}.png\” /></a></li>”)) . “”) : (“”)) . ”

“;

На эту:

$_ips___x_retval .= ”
” . (($data[‘share_enabled’]) ? (“” . (($data[‘customOutput’] and is_array( $data[‘customOutput’] )) ? (”
” . $this->registry->output->getTemplate($data[‘customOutput’][0])->{$data[‘customOutput’][1]}( $data[‘_rawUrl’], $title, $data[‘customOutput’][2] ) . ”
“) : (“<li><a href=\”” . $this->registry->getClass(‘output’)->formatUrl( $this->registry->getClass(‘output’)->buildUrl( “sharelink={$data[‘share_key’]};{$data[‘_url’]};{$title}”, “public”,” ), “”, “” ) . “” . (($data[‘overrideApp’]) ? (“&amp;overrideApp={$data[‘overrideApp’]}”) : (“”)) . “\” rel=\”nofollow\” target=\”_blank\” title=\”” . ((isset( $this->lang->words[‘gbl_sharelink_with_’ . $data[‘share_key’] ] )) ? (“{$this->lang->words[‘gbl_sharelink_with_’ . $data[‘share_key’] ]}”) : (“{$this->lang->words[‘gbl_sharelink_with’]} {$data[‘share_title’]}”)) . “\” class=’_slink’ id=’slink_{$data[‘share_key’]}’><img src=\”{$this->settings[‘public_cdn_url’]}style_extra/sharelinks/{$data[‘share_key’]}.png\” /></a></li>”)) . “”) : (“”)) . ”

“;

Бенчмарки php 7 в реальной жизни

Ну грех было не перейти на php 7, что я и сделал на одной из машин с production нагрузкой. И скажу, получилось здорово. Вот результат.

php5.6-to-php7-for-site

Потребление памяти (голубая линия) упало с 85% до 15% с последующим ростом до 30%. Нагрузка (uptime, смотрим скользящие средние на 15 минутных интервалах) – тоже с 0,25 до 0,10% (в абсолютных значениях). В общем, разработчики php 7 потрудились на славу.

Конфиги

System-V init-скрипт для php7-fpm
disk-save  /etc/init.d/php7-fpm

Утилита проверки конфига (нужна для скрипта выше)
disk-save /usr/local/lib/php7-fpm-checkconf

Ссылки

https://github.com/phpbrew/phpbrew/wiki/Requirement
https://github.com/phpbrew/phpbrew/wiki/Cookbook#install-phpbrew-into-system-wide-environment
https://www.howtoforge.com/tutorial/how-to-install-php-7-on-debian/
https://bjornjohansen.no/php7-fpm-nightly-build-on-ubuntu
http://www.zimuel.it/install-php-7/

http://stackoverflow.com/questions/33574632/how-do-i-install-php-extension-from-github

6 Comments

    1. Это The Dude с соответствующими линуксовыми пробами!))

    1. Велкам 🙂 Рад, что мои походы по граблям помогли обойти эти вот))

Leave a Comment