HHVM, Nginx и PHP (а также Laravel)

http://fideloper.com/hhvm-nginx-laravel
  • Перевод
  • Tutorial
HHVM + Nginx + PHP + LaravelМножество людей интересовалось установкой HHVM на Nginx для использования с Laravel. Давайте приступим.

HHVM (или HipHop Virtual Machine) — это виртуальная машина, предназначенная для выполнения программ, написанных на PHP. Использует технологию JIT компиляции для увеличение скорости выполнения байткода.

Вступление

Как и в большинстве моих статей, я буду использовать Ubuntu 12.04 LTS как сервер для установки нашего добра. Однако, мы вполне можем установить это все на Mac с помощью Brew (nginx и hhvm). Информация об установке HHVM на другие платформы (включая новые версии Ubuntu) может быть найдена здесь.

Ну что же, поехали!

Установка основы

Сначала, установим базовые вещи, необходимые для нашей цели:

$ sudo apt-get update
$ sudo apt-get install -y unzip vim git-core curl wget build-essential python-software-properties


Установка Nginx

Далее, установим Nginx. Почему он идет первым? Так как при установке пакета hhvm-fastcgi, он [пакет] изменит некоторые конфигурации Nginx, если обнаружит его.

$ sudo apt-get install -y nginx


Установка HHVM FastCGI

Судя по блогу HHVM мы можем установить HHVM с FastCGI. Следующий код установит HHVM и настроит для работы с FastCGI.

$ echo deb http://dl.hhvm.com/ubuntu precise main | sudo tee /etc/apt/sources.list.d/hhvm.list
$ sudo apt-get update
$ sudo apt-get install -y --force-yes hhvm-fastcgi

Примечание: я добавил флаг --force-yes для устранения некоторых проблем зависимостей.

Настройка HHVM

HHVM это по сути собственная версия PHP, поэтому нам не нужно устанавливать PHP отдельно. После установки вы можете использовать HHVM как обычный PHP. Для примера, вы можете исполнять php-файлы:

$ hhvm some_file.php

Так как у нас, вероятно, есть Composer и PHPUnit, которые предполагают доступность из командной строки, мы можем создать симлинк php на hhvm:

$ sudo ln -s `which hhvm` /usr/local/bin/php

Теперь мы можем использовать PHP как обычно!

$ php -v
HipHop VM v2.3.2 (rel)
Compiler: tags/HHVM-2.3.2-0-gf951cb8d8812c59344d5322454853b584b668636
Repo schema: 5b5a4fc9cde5a5d014d1dfdb491bf74e4e700131


HHVM Fast-CGI

Я использую Vagrant, и я хочу, чтобы моим корневым каталогом была директория /vagrant. Для изменения корня, нам нужно настроить как HHVM, так и Nginx.

Давайте начнем с HHVM. Файл для редактирования: /etc/hhvm/server.hdf Вот однострочная команда для выполнения:

# Change doc root from /var/www/ to /vagrant/
$ sudo sed -i 's/SourceRoot = \/var\/www\//SourceRoot = \/vagrant\//' /etc/hhvm/server.hdf 

Затем перезапускаем HHVM для применения изменений:

$ sudo service hhvm-fastcgi restart


Настраиваем Nginx

Теперь настроим Nginx. Я создам новый конфигурационный файл под названием vagrant:

# Create and edit our new configuration file
$ sudo vim /etc/nginx/sites-available/vagrant

Здесь вы можете увидеть конечное содержимое этого файла:

//  File /etc/nginx/sites-available/vagrant
server {
    root /vagrant;
    index index.html index.htm index.php;

    server_name localhost; # 192.168.33.10.xip.io if you are using Vaprobash

    include hhvm.conf;  # Include HHVM's configuration file for Nginx

    location / {
        try_files $uri $uri/ /index.php?q=$uri&$args;
    }

    location ~ /\.ht {
        deny all;
    }
}


Два важных замечания

Во-первых, мы не определяем блок location. Установка Nginx до HHVM представляет возможность HHVM увидеть Nginx и создать файл /etc/nginx/hhvm.conf для вас. Файл hhvm.conf, который мы подключаем, уже имеет блок location, нужный PHP.
Во-вторых, файл hhvm.conf предполагает корневой каталог /var/www. Это перезаписывает настройку root/vagrant. Нам нужно изменить это, чтобы наш vagrant-файл определял корневой каталог путем удаления директивы root в файле hhvm.conf:

$ sudo vim /etc/nginx/hhvm.conf
# Then comment out the line 'root /var/www' and save

Сам файл /etc/nginx/hhvm.conf:

location ~ \.php$ {
    # root /var/www
    fastcgi_keep_conn on;
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME /var/www$fastcgi_script_name;
    include        fastcgi_params;
}

Теперь включим виртуальный хост, который мы только что создали:

$ sudo ln -s /etc/nginx/sites-available/vagrant /etc/nginx/sites-enabled/vagrant


Теперь предстоит перезапустить HHVM-FastCGI и Nginx для вступления в силу изменений. Но сначала, создадим тестовый php-файл.

Немного PHP

Создадим простой тестовый файл:

$ vim /vagrant/index.php

Что-то простое вроде этого:

<?php
echo phpinfo(); // Expected output: HipHop

Дело за малым. Просто перезапускаем hhvm-fastcgi и nginx. После этого, вы сможете увидеть index.php при подключении к IP-адресу сервера (или к 192.168.33.10.xip.io, если вы юзаете Vaprobash) в браузере.

$ sudo service hhvm-fastcgi restart
$ sudo service nginx reload

Вы должны увидеть «HipHop» в браузере.

Laravel

В нашем случае установка Ларавела ничем не отличается от обычной установки оного. С тех пор, как мы симлинкнули PHP, все должно работать как часы. Давайте попробуем.

Установка Composer

Это будет обыкновенная глобальная инсталляция:

$ curl -sS https://getcomposer.org/installer | php
$ sudo mv composer.phar /usr/local/bin/composer


Установка Laravel

Теперь нам предоставляется возможность создать новый laravel-проект. Я назову его hhlaravel:

# Move to /vagrant so we install Laravel
# into /vagrant/hhlaravel
$ cd /vagrant
$ composer create-project laravel/laravel hhlaravel

Можете попить чая или кофе, пока установятся все зависимости :)

Последний шаг: настройка Laravel

Давайте сделаем маленький твик и установим корневой каталог в /public:

# Fast CGI document root
$ sudo sed -i 's/SourceRoot = \/vagrant\//SourceRoot = \/vagrant\/hhlaravel\/public\//' /etc/hhvm/server.hdf

# Nginx document root
sudo sed -i 's/root \/vagrant;/root \/vagrant\/hhlaravel\/public;/' /etc/nginx/sites-available/vagrant

# Reload configuration
$ sudo service hhvm-fastcgi restart
$ sudo service nginx reload

Все готово! Можете проверить работоспособность с помощью браузера.

Предостережения и примечания

Вам захочется уделять намного больше внимания на логи ошибок. По умолчанию, HHVM никаких ошибок в браузер не выводит. Проверьте лог ларавела:

# Show last 50 lines written out to laravel log
$ tail -n 50 -f /vagrant/hhlaravel/app/logs/laravel.log

Проверьте лог HHVM:

$tail -n 50 -f /var/log/hhvm/error.log

Вы также можете получать stack trace в ваши логи путем изменения конфигурации сервера.

Отредактируйте /etc/hhvm/server.hdf и добавьте директивы InjectedStackTrace и NativeStackTrace.
Log {
  Level = Warning
  AlwaysLogUnhandledExceptions = true
  RuntimeErrorReportingLevel = 8191
  UseLogFile = true
  UseSyslog = false
  File = /var/log/hhvm/error.log
  InjectedStackTrace = true
  NativeStackTrace = true
  Access {
    * {
      File = /var/log/hhvm/access.log
      Format = %h %l %u % t \"%r\" %>s %b
    }
  }
}

И наконец, вы можете добавить немного вывода в окно браузера путем добавления настроек Debug'а в /etc/hhvm/server.hdf:

Debug {
 FullBacktrace = true
 ServerStackTrace = true
 ServerErrorMessage = true
 TranslateSource = true
}

Однако помните, что журналы ошибок будут иметь более подробную информацию об ошибке. Здесь есть статья об использовании remote debugger'а для HHVM (на себе не испытывал).
Поделиться публикацией

Комментарии 42

    +4
    А зачем
    unzip build-essential python-software-properties
    ?
    Вы их напрямую не используете, а когда какому-то пакету они будут нужны — установятся автоматически, то же самое к vim — дело вкуса, и никак не обязательно, nano по-моему стоит по умолчанию в системе.

    А на счёт

    Примечание: я добавил флаг --force-yes для устранения некоторых проблем зависимостей.

    то это ничего не устраняет, и вообще чревато последствиями, лучше посмотреть в чём проблемы с зависимостями и испрвить их.

    Судя по посту конкретно для Laravel никаких хаков не нужно, а значит вполне достаточно github.com/facebook/hhvm/wiki/FastCGI
      0
      Извините, в никсах мало чего понимаю, так что корректно ответить навряд ли смогу :) Про дела вкуса — это выбор автора оригинальной статьи, каждый вправе использовать то, что ему нравится.
        +3
        Зачем вы автору перевода это пишете-то?
          +2
          Во время перевода можно было бы и исправить, а если нет понимания — то зачем копипастить.
            +2
            Правильно. Переводить — смысла нет.
              –1
              Вы не так поняли. Перевод имеет смысл, но это не отменяет того, что нужно понимать содержимое.
          0
          build-essential python-software-properties нужны для запуска add-apt-repository (и, кажется, еще каких-то утилит, связанных с пакетами). Эти команды кочуют из мануала в мануал.
            0
            Я знаю, для чего эти пакеты, но автор не использует apt-add-repository
              0
              python-software-properties это и есть штука без которой apt-add-repository не работает :-)
              build-essential тут непонятно для чего — ибо служит для сборки deb пакетов — автор пакетов не собирает тоже.
                0
                А мы о чём?
                В статье же

                $ echo deb http://dl.hhvm.com/ubuntu precise main | sudo tee /etc/apt/sources.list.d/hhvm.list
                

                apt-add-repository не используется
                  0
                  Я специально оставил смайлик в конце этой строки — говорящий об этом же.
                  А вообще "| sudo tee" это как бы странное решение само по себе.
                  ">" было бы как минимум проще написать (всмысле аж на 6 символов короче не считая пробелов)
                    +1
                    Вы правда не понимаете, зачем тут sudo tee и почему перенаправление не работает? Или Вы из тех, кто правит вордовские файлы под рутом?
                      +1
                      [Трольмод включен]
                      Если в статье используется "-y --force-yes", то править вордовские файлы под рутом это примерно такая же фигня.
                      На самом деле админы делятся на три вида:
                      1. Всё делают под рутом
                      2. Уже не всё делают под рутом (вы видимо относитесь к этой категории) — не самый плохой способ что-то делать
                      3. Достаточно понимают ЧТО они делают, чтоб делать это БЫСТРЕЕ под рутом :-)
                      [Трольмод выключен]
          +1
          На мой взгляд, было бы чуть более интересно, если бы Вы развернули под HHVM уже готовый проект на Laravel(как примечание автора) возможно появились какие либо ошибки и т.д и заодно можно было бы кратко оценить прирост производительности
            0
            PHP 5.5 на HHVM заведется?
              0
              Если вы имелете ввиду совместимость, то она на уровне ~ 90%
                0
                заведется, только вроде namespaces в HHVM не поддерживаются
                  0
                  устаревшая информация
                  тесты doctrine2 проходили на 99.95%, а это врятли возможно без поддержки наймспейсов

                    0
                    возможно. Давно не смотрел чего там у них поддерживалось или нет.
                    0
                    Поддерживается!) По крайней мере 2.3.0+
                    Я вообще под впечатлением о проделанной работе, скоро и MySQLi обещают судя по комментариям в GitHub.
                    Вот только моя поделка легко убивает HHVM с segfault, а почему ни я ни ребята из Facebook пока не поняли…
                      0
                      скоро и MySQLi

                      То есть сейчас наиболее распространенный экстеншен не работает под HHVM? А зачем он тогда?
                        0
                        Я как резервный вариант использую mysql_*()
                          0
                          объектный интерфейс удобнее :-)
                          mysql_* вроже же выкинуть обещали
                            0
                            В HHVM, наверное, не скоро выбросят.
                            А для объектного интерфейса придется обертку писать, если у вас уже какой-то абстракции нет, куда можно встроить функциональные вызовы.
                        0
                        а PDO поддерживается?
                +1
                Перевод с добавкой переводчики не всегда хорошо:
                HHVM — это не транслятор исходного кода, и т.д. по тексту, это переводчик скопипастил из вики, а зря, в исходном тексте такого небыло/
                HHVM — это виртуальная машина преднозначиная для выполнения программ написаных на PHP. Использует технологию JIT компиляции для увеличение скорости выполнения байткода.
                  +2
                  Исправил. В следующий раз можно в личку.
                    +2
                    Еще могу добавить что выбор fastcgi как протокола был выбран атором статьи зря, так как он не используется в продакшене фейсбуком — и сыроват пока
                    Вообще непонятно зачем вы занимаетесь переводом, если далеки от этой темы
                  –1
                  $sudo apt-get update

                  делать крайне нежелательно.
                  Рекомендуется

                  $ su -c 'apt-get update && apt-get upgrade'

                  а затем уже пакеты устанавливать.
                  И Nginx лучше использовать из репозитория Nginx.

                  Не менее, чем "--force-yes" вредна опция "-y" в install — практически гаратированный выстрел себе в ногу.
                  Присоединюсь к последнему комментарию, туториал — дело ответственное.
                  Прежде, чем опубликовать, нужно тщательно отттестировать и проверить.
                    0
                    Это чем же простое обновление списка пакетов хуже чем ещё и апгрейд всех пакетов, которые, к тому же, могут и не обновиться корректно (вы уверены, когда пользователь последний раз обновлял систему?)
                    Чем вам опция -y то не угодила?
                    -y, --yes, --assume-yes
                    Automatic yes to prompts; assume «yes» as answer to all prompts and
                    run non-interactively. If an undesirable situation, such as
                    changing a held package, trying to install a unauthenticated
                    package or removing an essential package occurs then apt-get will
                    abort. Configuration Item: APT::Get::Assume-Yes.

                    А вот force-yes, да, может быть опасно, о чем и упоминается в мане к apt-get.

                    Насчет установки из сторонних репозиториев и в частности nginx, сомневаюсь, что это правильно, ибо есть мейнтейнер и та версия, что есть в репах, она не просто так. Особенно в LTS релизах. Если хочется стабильно свежак, то да — сторонний репо, имхо.
                      0
                      Да мне все равно, используют эту опцию, или нет. Просто это плохая прктика.
                      Апгрейд системы делается для упорядочивания всех зависисмостей и приведения системы в актуальное состояние.
                      Это азы.
                      Следствием установки без апгрейда может быть несоответствие версий зависимостей и крах при установке ПО.
                      Это тоже азы.
                      Админ должен полностью контролировать процесс установки хотя бы потому, что, к примеру, в Debian при установке могут предлагаться альтернативы, и значения по умолчанию, в том числе конфигурация, могут не устраивать админа.
                      При этом система может запрашивать удаление конкурирующих пакетов, и при такой установке можно просто поломать систему.

                      Nginx имеет стабильный репозиторий, и он лучше подходит для использования. И не только из-за «плюшек».
                      Nginx репозиторий предлагает версию 1.4., тогда как precise (12.04) — 1.1.
                      Debian 7 — 1.2
                      Впрочем, если хочется использовать старую версию — пожалуйста.
                      И, по моему мнению — LTS — это просто миф.
                        0
                        Насчет установки из сторонних репозиториев и в частности nginx, сомневаюсь, что это правильно, ибо есть мейнтейнер и та версия, что есть в репах, она не просто так. Особенно в LTS релизах. Если хочется стабильно свежак, то да — сторонний репо, имхо.
                        habrahabr.ru/post/195742/#comment_6797402

                        Cтабильные пакеты лежат тут: nginx.org/ru/linux_packages.html — всё остальное сомнительно.
                          +1
                          Репозиторий nginx — не сторонний, а официальный.

                          Вы себе не представляете, сколько странных вещей мейнтенеры пакетов линукс-дистрибутивов делают «просто так». Если есть официальный репозиторий разработчика — он всегда лучше.
                        0
                        Автор, а профит-то есть от HHVM?) Бенчмарки не проводили?
                          0
                          Тестировал свой код, примерное ускорение в 2 раза было 3 месяца назад. Как только будет прохождение тестов yii 100%, вернусь к нему. Перспектива явно есть у данного проекта.
                            0
                            В официальном блоге пишут, что ускорение в 40 раз :/
                              0
                              Возможно все зависит от кода, я только сообщил о своем опыте, сравнения php-fpm 5.5 + opcache vs hhvm + apc. Возможно что уже стало лучше.
                              0
                              в 2 раза у чего, голого PHP-кода или со всем (БД, статика)?
                                0
                                БД и статика-то тут при чем? ) Естественно речь про код.
                                  0
                                  так о том и речь, что на реальном проекте разница может быть 5-10%, а не 40 раз
                            0
                            По причине появления хаба Laravel на хабре, отправляю сий пост туда, пусть будет первым.

                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                            Самое читаемое