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

// Апрель 1st, 2016 // PHP

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

dve_kiski_2

Задача

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

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

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

apt-get build-dep php5
apt-get install -y php5 php5-dev php-pear autoconf automake curl libcurl3-openssl-dev build-essential libxslt1-dev re2c libxml2 libxml2-dev php5-cli bison libbz2-dev libreadline-dev
apt-get install -y libfreetype6 libfreetype6-dev libpng12-0 libpng12-dev libjpeg-dev libjpeg8-dev libjpeg8 libgd-dev libgd3 libxpm4 libltdl7 libltdl-dev
apt-get install -y libssl-dev openssl
apt-get install -y gettext libgettextpo-dev libgettextpo0
apt-get install -y libicu-dev
apt-get install -y libmhash-dev libmhash2
apt-get install -y libmcrypt-dev libmcrypt4
apt-get install mysql-server mysql-client libmysqlclient-dev libmysqld-dev

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

su
sudo useradd -d /opt/phpbrew -m phpbrew
sudo adduser phpbrew sudo
sudo passwd phpbrew
sudo chsh -s /bin/bash phpbrew
cd /opt/phpbrew
su phpbrew

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

[[ -e ~/.phpbrew/bashrc ]] && source ~/.phpbrew/bashrc

Ставим его.

curl -L -O https://github.com/phpbrew/phpbrew/raw/master/phpbrew
chmod +x phpbrew
sudo mv phpbrew /usr/local/bin/phpbrew
phpbrew init

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

phpbrew known

phpbeew-known

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

phpbrew variants

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

phpbrew install 7.0.4 +fpm +gd +json +mbstring +mysql +pdo +opcache +curl +cli

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

tail -f /opt/phpbrew/.phpbrew/build/php-7.0.4/build.log

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

Installing shared extensions:     /opt/phpbrew/.phpbrew/php/php-7.0.4/lib/php/extensions/no-debug-non-zts-20151012/
Installing PHP CLI binary:        /opt/phpbrew/.phpbrew/php/php-7.0.4/bin/
Installing PHP CLI man page:      /opt/phpbrew/.phpbrew/php/php-7.0.4/php/man/man1/
Installing PHP FPM binary:        /opt/phpbrew/.phpbrew/php/php-7.0.4/sbin/
Installing PHP FPM config:        /opt/phpbrew/.phpbrew/php/php-7.0.4/etc/
Installing PHP FPM man page:      /opt/phpbrew/.phpbrew/php/php-7.0.4/php/man/man8/
Installing PHP FPM status page:   /opt/phpbrew/.phpbrew/php/php-7.0.4/php/php/fpm/
Installing phpdbg binary:         /opt/phpbrew/.phpbrew/php/php-7.0.4/bin/
Installing phpdbg man page:       /opt/phpbrew/.phpbrew/php/php-7.0.4/php/man/man1/
Installing PHP CGI binary:        /opt/phpbrew/.phpbrew/php/php-7.0.4/bin/
Installing PHP CGI man page:      /opt/phpbrew/.phpbrew/php/php-7.0.4/php/man/man1/
Installing build environment:     /opt/phpbrew/.phpbrew/php/php-7.0.4/lib/php/build/
Installing header files:           /opt/phpbrew/.phpbrew/php/php-7.0.4/include/php/
Installing helper programs:       /opt/phpbrew/.phpbrew/php/php-7.0.4/bin/
  program: phpize
  program: php-config
Installing man pages:             /opt/phpbrew/.phpbrew/php/php-7.0.4/php/man/man1/
  page: phpize.1
  page: php-config.1
/opt/phpbrew/.phpbrew/build/php-7.0.4/build/shtool install -c ext/phar/phar.phar /opt/phpbrew/.phpbrew/php/php-7.0.4/bin
ln -s -f phar.phar /opt/phpbrew/.phpbrew/php/php-7.0.4/bin/phar
Installing PDO headers:           /opt/phpbrew/.phpbrew/php/php-7.0.4/include/php/ext/pdo/

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

cp /opt/phpbrew/.phpbrew/php/php-7.0.4/etc/php-fpm.d/www.conf.default /opt/phpbrew/.phpbrew/php/php-7.0.4/etc/php-fpm.d/www.conf

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

Включаем Zend Opcode Cache

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

[opcache]
zend_extension=opcache.so
opcache.enable_cli=1
opcache.save_comments=0
opcache.fast_shutdown=1
opcache.validate_timestamps=1
opcache.revalidate_freq=60
opcache.use_cwd=1
opcache.max_accelerated_files=100000
opcache.max_wasted_percentage=5
opcache.memory_consumption=128
opcache.consistency_checks=0

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

zend_opcache

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

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

sudo mcedit /usr/local/lib/php7-fpm-checkconf

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

#!/bin/sh
set -e
errors=$(/opt/phpbrew/.phpbrew/php/php-7.0.4/sbin/php-fpm --fpm-config /opt/phpbrew/.phpbrew/php/php-7.0.4/etc/php-fpm.conf -t 2>&1 | grep "\[ERROR\]" || true);
if [ -n "$errors" ]; then
    echo "Please fix your configuration file…"
    echo $errors
    exit 1
fi
exit 0

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

tr -d '\015' < ./php7-fpm-checkconf.txt > ./php7-fpm-checkconf

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

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

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

cd /etc/init.d/
sudo wget http://tokarchuk.ru/wp-content/uploads/2016/03/php7-fpm.txt
sudo touch /etc/init.d/php7-fpm
sudo chmod +x /etc/init.d/php7-fpm
su
tr -d '\015' < /etc/init.d/php7-fpm.txt > /etc/init.d/php7-fpm
exit
sudo ln -s /opt/phpbrew/.phpbrew/php/php-7.0.4/sbin/php-fpm /usr/sbin/php7-fpm
sudo chmod +x /etc/init.d/php7-fpm
sudo rm -rf /etc/init.d/php7-fpm.txt

или вручную:

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

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

#!/bin/sh
### BEGIN INIT INFO
# Provides: php7-fpm
# Required-Start: $remote_fs $network
# Required-Stop: $remote_fs $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts php7-fpm
# Description: Starts The PHP FastCGI Process Manager Daemon
### END INIT INFO

# Author: Ondrej Sury <ondrej@debian.org>
# Adapted to php7-fpm by @bjornjohansen

PATH=/opt/phpbrew/.phpbrew/php/php-7.0.4/sbin:/sbin:/usr/sbin:/bin:/usr/bin
DESC="PHP7 FastCGI Process Manager"
NAME=php7-fpm
DAEMON=/usr/sbin/$NAME
DAEMON_ARGS="--daemonize --fpm-config /opt/phpbrew/.phpbrew/php/php-7.0.4/etc/php-fpm.conf"
PIDFILE=/var/run/php7-fpm.pid
TIMEOUT=30
SCRIPTNAME=/etc/init.d/$NAME
...

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

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

sudo ln -s /opt/phpbrew/.phpbrew/php/php-7.0.4/sbin/php-fpm /usr/sbin/php7-fpm

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

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

[Unit]
Description=The PHP 7 FastCGI Process Manager
After=network.target

[Service]
Type=simple
PIDFile=/var/run/php7-fpm.pid
ExecStartPre=/usr/local/lib/php7-fpm-checkconf
ExecStart=/usr/sbin/php7-fpm --nodaemonize --fpm-config /opt/phpbrew/.phpbrew/php/php-7.0.4/etc/php-fpm.conf
ExecReload=/bin/kill -USR2 $MAINPID

[Install]
WantedBy=multi-user.target

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

tr -d '\015' < ./php7-fpm.service.txt > ./php7-fpm.service

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

sudo systemctl daemon-reload

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

pid = /var/run/php7-fpm.pid

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

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

sudo /etc/init.d/php7-fpm start
ps aux | grep php

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

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

phpbrew switch 7.0.4
phpbrew ext install https://github.com/php/pecl-database-mysql.git

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

===> Installing mysql extension...
Log stored at: /opt/phpbrew/.phpbrew/build/php-7.0.4/ext/mysql/build.log
Changing directory to /opt/phpbrew/.phpbrew/build/php-7.0.4/ext/mysql
===> Phpize...
===> Configuring...
===> Building...
===> Running make all: make -C /opt/phpbrew/.phpbrew/build/php-7.0.4/ext/mysql                                                      all  >> /opt/phpbrew/.phpbrew/build/php-7.0.4/ext/mysql/build.log 2>&1
===> Installing...
===> Running make install: make -C /opt/phpbrew/.phpbrew/build/php-7.0.4/ext/mys                                                    ql  install  >> /opt/phpbrew/.phpbrew/build/php-7.0.4/ext/mysql/build.log 2>&1
===> Extension is installed.
===> Creating config file /opt/phpbrew/.phpbrew/php/php-7.0.4/var/db/mysql.ini.d                                                    isabled
===> Enabling extension mysql
[*] mysql extension is enabled.
Done.

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

sudo service php7-fpm restart

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

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

sudo apt-get install libwebp5 libwebp-dev
phpbrew --debug ext install gd -- \
--enable-gd-native-ttf \
--with-gd=shared \
--with-freetype-dir=/usr/include/freetype2/freetype \
--with-jpeg-dir=/usr \
--with-libdir=lib/x86_64-linux-gnu \
--with-png-dir=/usr \
--with-vpx-dir=/usr \
--with-xpm-dir=/usr \
--with-webp-dir=/usr

Установка 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

cd /home/www-data/db.site.ru
git clone --depth=1 --branch=STABLE https://github.com/phpmyadmin/phpmyadmin.git ./html
cp config.sample.inc.php config.inc.php

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

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

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

sudo mkdir /usr/include/freetype2/freetype
sudo ln -s /usr/include/freetype2/freetype.h /usr/include/freetype2/freetype/freetype.h
sudo ln -s /usr/lib/x86_64-linux-gnu/libjpeg.so.62.0.0 /usr/lib/libjpeg.so shu
sudo ln -s /lib/x86_64-linux-gnu/libpng12.so.0.50.0 /usr/lib/libpng.so 
sudo ln -s /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18.0.0 /usr/lib/libmysqlclient.so
sudo mkdir /usr/lib/x86_64-linux-gnu/mysql/
sudo ln -s /usr/bin/mysql_config /usr/lib/x86_64-linux-gnu/mysql_config
phpbrew install http://museum.php.net/php5/php-5.2.17.tar.bz2 +mysql=/usr/bin/mysql_config +gd +curl +cgi +mbstring +mcrypt -- --enable-fastcgi --enable-discard-path --enable-force-cgi-redirect
// после скачивания дистрибьютива и попытки компиляции будет вылетать с ошибкой, надо накатить патч и повторить компиляцию
// добавляем патч по libxml29
cd ~/.phpbrew/build/php-5.2.17/
wget https://mail.gnome.org/archives/xml/2012-August/txtbgxGXAvz4N.txt
patch -p0 < ./txtbgxGXAvz4N.txt
// компилируем второй раз
phpbrew install http://museum.php.net/php5/php-5.2.17.tar.bz2 +mysql=/usr/bin/mysql_config +gd +curl +cgi +mbstring +mcrypt -- --enable-fastcgi --enable-discard-path --enable-force-cgi-redirect

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

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

/opt/phpbrew/.phpbrew/php/php-5.2.17/bin/php-cgi

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

sudo apt-get install spawn-fcgi

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

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

mcedit /opt/phpbrew/php5.2.17.fcgi

#!/bin/bash

FASTCGI_USER=www-data
FASTCGI_GROUP=www-data
ADDRESS=127.0.0.1
PORT=9020
PIDFILE=/var/run/php5.2.17-fastcgi.pid
CHILDREN=2
PHP5=/opt/phpbrew/.phpbrew/php/php-5.2.17/bin/php-cgi

/usr/bin/spawn-fcgi -a $ADDRESS -p $PORT -P $PIDFILE -C $CHILDREN -u $FASTCGI_USER -g $FASTCGI_GROUP -f $PHP5

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

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

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

#!/bin/bash
### BEGIN INIT INFO
# Provides: php5.2.17-fpm
# Required-Start: $remote_fs $network
# Required-Stop: $remote_fs $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts php5.2.17-fpm
# Description: Starts The PHP FastCGI Process Manager Daemon
### END INIT INFO
PHP_SCRIPT=/opt/phpbrew/php5.2.17.fcgi
FASTCGI_USER=www-data
FASTCGI_GROUP=www-data
PID_DIR=/var/run
PID_FILE=/var/run/php5.2.17-fastcgi.pid
RET_VAL=0

case "$1" in
 start)
 if [[ ! -d $PID_DIR ]]
 then
 mkdir $PID_DIR
 chown $FASTCGI_USER:$FASTCGI_GROUP $PID_DIR
 chmod 0770 $PID_DIR
 fi
 if [[ -r $PID_FILE ]]
 then
 echo "php-fastcgi already running with PID `cat $PID_FILE`"
 RET_VAL=1
 else
 $PHP_SCRIPT
 RET_VAL=$?
 fi
 ;;
 stop)
 if [[ -r $PID_FILE ]]
 then
 kill `cat $PID_FILE`
 rm $PID_FILE
 RET_VAL=$?
 else
 echo "Could not find PID file $PID_FILE"
 RET_VAL=1
 fi
 ;;
 restart)
 if [[ -r $PID_FILE ]]
 then
 kill `cat $PID_FILE`
 rm $PID_FILE
 RET_VAL=$?
 else
 echo "Could not find PID file $PID_FILE"
 fi
 $PHP_SCRIPT
 RET_VAL=$?
 ;;
 status)
 if [[ -r $PID_FILE ]]
 then
 echo "php-fastcgi running with PID `cat $PID_FILE`"
 RET_VAL=$?
 else
 echo "Could not find PID file $PID_FILE, php-fastcgi does not appear to be running"
 fi
 ;;
 *)
 echo "Usage: php-fastcgi {start|stop|restart|status}"
 RET_VAL=1
 ;;
esac

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

chmod +x /etc/init.d/php5.2.17-fpm
chmod 0755 /opt/phpbrew/php5.2.17.fcgi
/etc/init.d/php5.2.17-fpm start
ps aux | grep php

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

/etc/init.d/php5.2.17-fpm stop
ps aux | grep php

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

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

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

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

[Unit]
Description=The PHP 5.2.17 FastCGI Process Manager
After=network.target

[Service]
Type=simple
PIDFile=/var/run/php5.2.17-fastcgi.pid
ExecStart=/opt/phpbrew/php5.2.17.fcgi
ExecReload=/bin/kill -USR2 $MAINPID

[Install]
WantedBy=multi-user.target

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

sudo systemctl daemon-reload
update-rc.d php5.2.17-fpm defaults 
sudo update-rc.d php5.2.17-fpm enable
 

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

# PHP-FPM (backend)
upstream php52 {
server 127.0.0.1:9020;
}

 
# Конфиг Nginx (frontend)
server {
 

# Защита от бага http://forum.nginx.org/read.php?2,154025,154036
# server_name_in_redirect off;
 
# Защита от бага upstream-sent-too-big-header
fastcgi_buffers 8 32k;
fastcgi_buffer_size 32k;
 
# Порт, принимаемые HOST и путь к сайту
listen 80;
server_name site.org;
 
set $www_folder '/home/www-data';
set $root_path '$www_folder/$host/html';
 
# for turbo realpath extension http://php.webtutor.pl/en/2011/07/01/running-php-on-nfs-new-version-of-turbo_realpath-extension/
fastcgi_param realpath_cache_basedir '/tmp:/usr/share/php:/usr/share/phpmyadmin:$root_path';
# root $root_path;
index index.htm index.html index.php;
 
# Запросы на картинки, стили и другую статику
location ~* \.(css|js|swf|ico|png|jpg)$ {
root $root_path;
access_log off;
expires  30d;
}

 
# Защита от брутфорса
location ~ ^/(wp-login\.php) {
auth_basic "Admin zone";
auth_basic_user_file /home/www-data/.htpasswd;
 
index index.htm index.html index.php;
include /etc/nginx/fastcgi_params;
fastcgi_param SERVER_NAME $http_host; # For correct $_SERVER['HTTP_HOST'] after fastcgi_params
fastcgi_param SCRIPT_FILENAME $root_path/$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $root_path; # этот параметр нужен несмотря на root в секции server
# fastcgi_param REMOTE_ADDR $http_x_real_ip;
fastcgi_pass php52;
}

 
# Запросы непосредственно .php-файлов, например утилит или index.php (не кэшируются)
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_param SERVER_NAME $http_host; # For correct $_SERVER['HTTP_HOST'] after fastcgi_params
fastcgi_param SCRIPT_FILENAME $root_path/$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $root_path; # этот параметр нужен несмотря на root в секции server
# fastcgi_param REMOTE_ADDR $http_x_real_ip;
fastcgi_pass php52;
fastcgi_read_timeout 900; # 15 minutes
}

# Копия предыдущего для internal переадресации
location @phpscripts {
include /etc/nginx/fastcgi_params;
fastcgi_param SERVER_NAME $http_host; # For correct $_SERVER['HTTP_HOST'] after fastcgi_params
fastcgi_param SCRIPT_FILENAME $root_path/$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $root_path; # этот параметр нужен несмотря на root в секции server
# fastcgi_param REMOTE_ADDR $http_x_real_ip;
fastcgi_pass php52;
fastcgi_read_timeout 900; # 15 minutes
}

 

# Остальные запросы также идут на PHP-FPM, если $uri не существует (через memcache)

location / {
default_type text/html; #add_header    Content-Type  "text/html";
root  $root_path;
 
if (!-e $request_filename) {
return 404;
}
error_page      404 502 504 403 405 = @php;
}

 

# Для отладки
location /status {
include /etc/nginx/fastcgi_params;
fastcgi_param SERVER_NAME $http_host; # For correct $_SERVER['HTTP_HOST'] after fastcgi_params
fastcgi_param SCRIPT_FILENAME $root_path/index.php;
fastcgi_pass php52;
}

 

location /ping {
include /etc/nginx/fastcgi_params;
fastcgi_param SERVER_NAME $http_host; # For correct $_SERVER['HTTP_HOST'] after fastcgi_params
fastcgi_param SCRIPT_FILENAME $root_path/index.php;
fastcgi_pass php52;
}

 
# Веб-приложение
location @php {
include /etc/nginx/fastcgi_params;
fastcgi_param SERVER_NAME $http_host; # For correct $_SERVER['HTTP_HOST'] after fastcgi_params
fastcgi_param SCRIPT_FILENAME $root_path/index.php;
# fastcgi_param REMOTE_ADDR $http_x_real_ip;
fastcgi_pass php52;
fastcgi_read_timeout 900; # 15 minutes
}
 
# Переопеределение 502 ошибки
error_page     502 = /502.htm;
location = /502.htm {
root  $www_folder;
}
 
 
# Защита от просмотра .htaccess и .htpasswd файлов
location ~ /\.ht {
deny  all;
}
 
# Защита от просмотра svn-файлов
location ~ /.svn/ {
deny all;
}

 
# Статус запросы (/status) и пинг(/ping) запросы от системы мониторинга
location ~ ^/(status|ping)$ {
include fastcgi_params;
fastcgi_param SERVER_NAME $http_host; # For correct $_SERVER['HTTP_HOST'] after fastcgi_params
fastcgi_pass 127.0.0.1:9010;
fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
allow 127.0.0.1;
deny all;
}

 
# awstats
location ^~ /awstats-icon {
alias /usr/share/awstats/icon/;
access_log off;
}

 
location ^~ /awstatscss {
alias /usr/share/doc/awstats/examples/css/;
access_log off;
}
 
location ^~ /awstatsclasses {
alias /usr/share/doc/awstats/examples/classes/;
access_log off;
}
 
location ~ ^/cgi-bin {
fastcgi_pass unix:/var/run/fcgiwrap.socket;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME /usr/lib$fastcgi_script_name;
}
}

Бенчмарки 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

Share

Спасибо!


Если вам помогла статья, или вы хотите поддержать мои исследования и блог - вот лучший способ сделать это:


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

  1. gtalex.ru:

    Привет!
    Чем такие графики можно генерировать?

  2. […] это была очень правильная мысль). За основу была взята статья но не всё пошло так гладко — пришлось […]

Комментировать