Статьи

Могут ли приложения Symfony быть быстрыми на Vagrant? Давайте проверим с SuluCMS!

В этом коротком руководстве мы создадим Sulu , новую CMS на основе Symfony, и оптимизируем ее в среде Vagrant . Почему специальный учебник по этому вопросу? Помимо того факта, что Sulu имеет довольно сложную процедуру инициализации, она основана на Symfony, который очень медленно работает на виртуальных машинах с общими файловыми системами и, следовательно, нуждается в дополнительной оптимизации после установки. Хаки производительности в этом посте, хотя и специфичны для Sulu, могут быть применены к любому приложению Symfony, чтобы ускорить его на Vagrant.


Хотите узнать больше о Symfony и / или SuluCMS? Присоединяйтесь к нам на WebSummerCamp — единственной конференции, наполненной до краев длинными практическими семинарами. Программа вышла и она потрясающая ! Супер ранние билеты доступны до конца июня!


логотип сулу

Как обычно, мы будем использовать нашу коробку Homestead Improved в качестве основы, но приведенные ниже шаги объяснены достаточно подробно, чтобы вы могли следовать им в любой среде.

Новая коробка и общий доступ к папкам

Мы начинаем с загрузки новой коробки и настройки общего доступа к папкам.

git clone https://github.com/swader/homestead_improved hi_sulu cd hi_sulu; bin/folderfix.sh 

Как только это будет сделано, рекомендуется установить тип общего доступа к файлам nfs из-за этой известной проблемы , также описанной здесь .

Тип приложения и Vagrant Boot

Homestead Improved поставляется с типом приложения symfony-sulu , который специально настраивает Nginx для Sulu. Мы добавляем новый сайт в Homestead.yaml :

  - map: test.app to: /home/vagrant/Code/sulu/web type: symfony-sulu 

Сгенерированный Nginx ниже. Если вы используете что-то отличное от Homestead Improved, рекомендуем вам скопировать его отсюда:

 server { listen 80; listen 443 ssl; server_name test.app; root "/home/vagrant/Code/sulu/web"; charset utf-8; location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } access_log off; error_log /var/log/nginx/test.app-ssl-error.log error; sendfile off; client_max_body_size 100m; # PROD location ~ ^/(website|admin|app)\.php(/|$) { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_intercept_errors off; fastcgi_buffer_size 16k; fastcgi_buffers 4 16k; # Prevents URIs that include the front controller. This will 404: # http://domain.tld/app.php/some-path # Remove the internal directive to allow URIs like this internal; } # strip app.php/ prefix if it is present rewrite ^/app\.php/?(.*)$ /test.app permanent; location /admin { index admin.php; try_files $uri @rewriteadmin; } location @rewriteadmin { rewrite ^(.*)$ /admin.php/test.app last; } location / { index website.php; try_files $uri @rewritewebsite; } # expire location ~* \.(?:ico|css|js|gif|jpe?g|png)$ { try_files $uri /website.php/test.app; access_log off; expires 30d; add_header Pragma public; add_header Cache-Control public; } location @rewritewebsite { rewrite ^(.*)$ /website.php/test.app last; } location ~ /\.ht { deny all; } ssl_certificate /etc/nginx/ssl/test.app.crt; ssl_certificate_key /etc/nginx/ssl/test.app.key; } 

Удалите строки SSL внизу, если вы не используете HTTPS.


Тогда давайте загрузим в нее виртуальную машину и SSH.

 vagrant up; vagrant ssh 

Добавьте test.app (или другой URL, если вы его выбрали) в файл etc/hosts вашей операционной системы. Если это предложение не имеет смысла, прочитайте, пожалуйста, краткое описание Homestead Improved Quick Start .

Установка Сулу

Все шаги ниже происходят внутри виртуальной машины.

 cd Code git clone https://github.com/sulu-io/sulu-standard sulu; cd sulu git checkout master composer install 

Это займет некоторое время и может потребовать токен аутентификации Github.

Обратите внимание, что в зависимости от установленной версии PHP, эта команда может завершиться ошибкой. Например, для Zend-кода на момент написания этой статьи требуется PHP любой версии, отличной от 7.0.5, и, кстати, именно эта версия установлена ​​на Homestead Improved 0.4.4. Это легко исправить, запустив sudo apt-get upgrade php7.0-fpm .

Скрипты после установки запросят у нас некоторые параметры — единственные, которые нам нужно заполнить, — это имя базы данных ( homestead , если вы не создали ее специально для Sulu) и учетные данные ( homestead / secret ). Для других можно оставить значения по умолчанию на данный момент и настроить позже, если это необходимо.

Конфигурирование Сулу

 cp app/Resources/webspaces/sulu.io.xml.dist app/Resources/webspaces/sulu.io.xml cp app/Resources/pages/default.xml.dist app/Resources/pages/default.xml cp app/Resources/pages/overview.xml.dist app/Resources/pages/overview.xml cp app/Resources/snippets/default.xml.dist app/Resources/snippets/default.xml rm -rf app/cache/* rm -rf app/logs/* 

Выше устанавливается веб-пространство по умолчанию.

В файле app/Resources/webspaces/sulu.io.xml мы заменяем name и key на значения, которые мы предпочитаем.

После этого мы запускаем:

 app/console sulu:build dev 

Приведенная выше команда сгенерирует пользователя admin с паролем admin и выполнит некоторые другие удобные для разработки инициализации. Рекомендуется запускать это в средах разработки. Обратите внимание, что эта команда никогда не должна выполняться в рабочей среде . Вместо этого в производственной app/console sulu:build prod вы запускаете app/console sulu:build prod .

В качестве отступления: на данный момент у нас есть администратор с работающими учетными данными admin/admin . Чтобы создать новые роли в будущем, мы выполняем:

 app/console sulu:security:role:create 

и чтобы создать больше пользователей, мы выполняем:

 app/console sulu:security:user:create 

test.app/admin часть в test.app/admin должна работать сейчас, хотя и очень медленно.

Экран входа администратора

Для работы внешнего интерфейса мы используем:

 app/console assetic:dump 

Это создаст необходимые файлы JS и CSS и включит их в тему по умолчанию.

В качестве завершающего подготовительного шага, давайте включим режим разработки, изменив строку:

 defined('SYMFONY_ENV') || define('SYMFONY_ENV', getenv('SYMFONY_ENV') ?: 'prod'); 

в

 defined('SYMFONY_ENV') || define('SYMFONY_ENV', getenv('SYMFONY_ENV') ?: 'dev'); 

как в web/admin.php и в web/website.php . Это предоставит нам знаменитую панель отладки Symfony внизу экрана.

Улучшения скорости

Приложения Symfony, как известно, работают медленно на Vagrant. Следующие шаги позволят сократить время загрузки страницы с 25 секунд на маршрут (включая вызовы ajax) до примерно 400 мс на маршрут, независимо от платформы операционной системы хоста или типа общего доступа к файлам . Другие руководства часто фокусируются на NFS или других проблемах, о которых известно, что они работают только в некоторых операционных системах, но эта процедура гарантированно творит чудеса при любой настройке.

Лог и кеш

В app/AbstractKernel.php замените методы getLogDir и getCacheDir на эти:

  /** * {@inheritDoc} */ public function getCacheDir() { if (in_array($this->environment, array('dev', 'test'))) { return '/dev/shm/appname/cache/' . $this->getContext() . '/' . $this->environment; } return $this->rootDir . '/cache/' . $this->getContext() . '/' . $this->environment; } /** * {@inheritDoc} */ public function getLogDir() { if (in_array($this->environment, array('dev', 'test'))) { return '/dev/shm/appname/logs' . $this->getContext() . '/' . $this->environment; } return $this->rootDir . '/logs/' . $this->getContext() . '/' . $this->environment; } 

Это вынуждает Sulu записывать журналы и кэш в папку, не используемую совместно с операционной системой хоста, что позволяет избежать быстрой записи неважных данных на общий жесткий диск.

Переезд продавца

Приложения Symfony печально известны тем, что устанавливают сотни пакетов — даже инфраструктура по умолчанию переполняется ими, не говоря уже о приложениях, построенных на нем. Когда на жестком диске нужно искать так много классов, и жесткий диск используется совместно с виртуальной машиной и основной операционной системой, как это происходит с Vagrant, время загрузки, очевидно, медленно.

Поскольку практически нет шансов, что мы когда-либо будем редактировать что-либо внутри папки vendor , мы можем переместить это из синхронизированных папок в место внутри виртуальной машины, которое является локальным только для «диска» машины. Это означает, что мы теряем синхронизируемость и вынуждены запускать команды composer исключительно из виртуальной машины (или через прокси-сервер из хост-ОС, но это выходит за рамки этого поста), но все ради невероятного увеличения скорости.

Чтобы автоматически сделать это, внутри папки sulu выполните:

 ~/Code/bin/sulu/vendorfix.sh 

(в качестве альтернативы см. ниже полную процедуру того, что вам нужно сделать )

Это изменит некоторые пути в composer.json , app/autoload.php и app/config/sulu.yml , удалит папку текущего vendor и запустит установку Composer. Изучите сценарий оболочки, чтобы увидеть, что он делает, если вам интересно, или посмотрите следующий раздел.

Чтобы сохранить автозаполнение в своей IDE, добавьте home/vagrant/vendors/sulu-test.app/ в путь включения вашей IDE. Вам, вероятно, придется скопировать папку vendor в хост-систему где-нибудь — такая команда должна помочь:

 cp -R ~/vendors/sulu-test.app ~/Code/ 

Затем просто выполните следующие действия в IDE, например, PhpStorm:

Включить путь в PhpStorm

Перемещение продавца: долгий путь

Как наиболее важная часть оптимизации (т. vendorfix.sh которая приносит наибольшее количество результатов), подход, vendorfix.sh на vendorfix.sh поставщиков, заслуживает большего разъяснения, чтобы его можно было легко реплицировать в средах без HI, в которых нет сценария vendorfix.sh . Далее следует пошаговая процедура (пропустите ее, если вы использовали вышеуказанный шаг, и он работал нормально):

  1. Выберите местоположение только для виртуальной машины для папки вашего поставщика. Рекомендуется поместить их все в одну папку, а затем расположить каждого поставщика в подпапку для проекта. Например: /home/vagrant/vendors/sulu-myapp . Давайте предположим, что проект будет называться myapp . Создайте эту папку:

     mkdir -p /home/vagrant/vendors/sulu-myapp 
  2. Измените конфигурацию в composer.json чтобы отразить это местоположение нового vendor , изменив или добавив значение config :

      "config": { "vendor-dir": "/home/vagrant/vendors/sulu-sulu.io/", "bin-dir": "vendor/bin" }, 
  3. Откройте app/autoload.php и замените строку, объявляющую $loader на путь, ведущий к нашему новому настраиваемому местоположению vendor :

     // $loader = require __DIR__ . '/../vendor/autoload.php'; $loader = require "/home/vagrant/vendors/sulu-myapp/autoload.php"; 
  4. Откройте app/config/sulu.yml и замените все экземпляры %kernel.root_dir%/../vendor/ на полный путь к нашей новой папке vendor. Это должно происходить в двух местах: конфигурация Doctrine вверху и запись sulu_core.content.structure.sulu в середине файла.

  5. Удалите старую папку с помощью rm -rf vendor из папки приложения ( myapp ).

  6. Запустите composer install и composer update чтобы убедиться, что все прошло хорошо.

  7. Очистить кэш с помощью app/console cache:clear .

Вот и все. Пользовательское местоположение продавца теперь должно быть настроено. Пожалуйста, напишите ниже, если у вас возникнут какие-либо трудности.

Обратите внимание, что хотя этот процесс специфичен для Sulu, он применяется к любому приложению Symfony (или к любому приложению по этому вопросу). То, к чему это сводится, определяет пользовательскую папку вендора в composer.json и заменяет все ссылки на местоположение старой папки вендора путями к новой.

Автозагрузка APC

Разрешите кэширование APC для автозагрузчика, раскомментировав соответствующие строки в web/website.php и web/admin.php . Нам нужен APC, чтобы использовать это, но Homestead Improved уже оборудовано для этого.

Разнообразный

  • мы можем обновить значение realpath_cache_size в /etc/php/7.0/fpm/php.ini до большего значения, например 4096k, и realpath_cache_ttl до 7200.

  • мы можем получить незначительный выигрыш, установив расширение C для Twig .

  • мы можем отключить XDebug с помощью:

     sudo phpdismod xdebug; sudo service php7.0-fpm restart 

Исправление проблем

Оптимизация отладки Symfony

Приложения Symfony, состоящие из ненормального числа классов и файлов, обычно собирают свои основные файлы в один файл app/bootstrap.php.cache . Это делает практически невозможным правильную отладку приложений Symfony без дальнейших изменений. Чтобы упростить отладку, обратитесь к этим документам .

__php_incomplete_class не имеет десериализатора

Обычно это происходит из-за устаревшего кэша. Во-первых, оптимизируйте среду для отладки (см. Выше). Потом:

 app/console cache:clear rm -rf app/cache/* composer update 

Кроме того, если вы используете APC, уничтожьте кеш (см. Ниже).

Изменения не имеют никакого эффекта / классы ищутся в неправильном месте

Обычно это происходит, когда кэш APC должен быть отключен. Один из способов сделать это — поместить:

 apc_clear_cache(); 

в верхней части website.php или admin.php , в зависимости от того, что вы используете, а затем удалите его после первого запроса. Или просто создайте отдельный файл с помощью этой команды, чтобы вы могли вызывать его в любое время.

Вывод

И http://test.app/admin и http://test.app (если вы использовали домен vhost) теперь должны работать и работать молниеносно. Вы должны быть готовы начать разработку своего приложения на базе CMS в Sulu.

Как мы упоминали выше, эти хаки, по общему признанию, специфичны для Sulu, но могут применяться к любому приложению Symfony. Наиболее важными из них являются исправление поставщика и исправление журнала / кэша, они значительно улучшат время загрузки приложения во время разработки. Другие хаки также удобны для производства и могут быть использованы для ускорения приложения при развертывании.

Если у вас есть какие-либо другие советы и рекомендации, которые вы хотели бы поделиться для повышения производительности приложений Symfony, сред разработки на основе Vagrant или обоих — Symfony на Vagrant — пожалуйста, сообщите нам об этом в разделе комментариев ниже, и мы сделаем все возможное, обновить пост.


Хотите узнать больше о Symfony и / или SuluCMS? Присоединяйтесь к нам на WebSummerCamp — единственной конференции, наполненной до краев длинными практическими семинарами. Программа вышла и она потрясающая ! Супер ранние билеты доступны до конца июня!