Установка WordPress на Windows Server 2012 / Windows 8
В этой заключительной статье цикла, описывающего развертывание веб-сайта на базе IIS с поддержкой PHP и MySQL, мы опишем типовой сценарий установки на нашем сервере «движка» сайта на примере самой популярной на данный момент системы управления контентом (CMS) блогового типа — WordPress.
Итак, предполагается, что на нашем сервере уже установлены:
- IIS с поддержкой PHP (Установка IIS с PHP на Windows)
- Система управления БД MySQL (Установка MySQL на Windows)
- Опционально, для удобства работы с базами данных MySQL можно установить скрипт phpMyAdmin.
Автоматическая установка WordPress
Проще всего развернуть сайт с WordPress с помощью, уже знакомого нам по предыдущим статьям цикла, универсального установщика Microsoft Web Platform Installer (Web PI). Запускаем его и в поле поиска вбиваем wordpress.
Находим в списке продуктов WorpPress, нажимаем Add, а затем Install.
В процессе развертывания сайта WordPress, Web PI автоматически создаст новую базу данных MySQL и пользователя (имя БД, пользователя и его пароль будут отображены на экране установки, в случае необходимости их можно сохранить).
Также будет создан отдельный сайт IIS, живущий на определенном порту (номер порта генерируется установщиком). В нашем примере был создан сайт на порту 30205 с адресом http://localhost:30205 .
После завершения установки в браузере автоматически откроется новое окно, в котором необходимо заполнить следующие поля: заголовок сайта, имя администратора сайта, пароль и e-mail администратора сайта WordPress.
Для завершения установки осталось нажать кнопку Install Wordpress. Дождитесь выполнения скрипта, после чего можно перейти в панель управления WordPress по адресу http://localhost:30205/wp-login.php
Итак, перед нами открылась административная панель WordPress (админка) и можно приступать непосредственно к настройке и наполнению сайта.
Существенный недостаток установки WordPress с помощью WebPI – большое количество «лишних» компонентов, которые устанавливаются вместе с ним.
На скриншоте выделены компоненты, которые были установлены вместе с CMS WordPress. Как видите, их не мало.
И самое главное, вместо нашего «родного» сервера IIS для установленного сайта будет использоваться отдельный инстанс IIS Express 8.0.
Ручная установка WordPress на IIS
Прежде, чем приступить к ручной установке WordPress на Windows 8, нужно выполнить ряд подготовительных операций.
В первую очередь необходимо создать базу данных для хранения данных WordPress и пользователя с правами доступа к этой базе данных. Создать базу и пользователя можно через phpMyAdmin, либо непосредственно из командной строки MySQL.
Открываем командную оболочку MySQL (MySQL Command Line Shell), указываем пароль администратора сервера MySQL (root) и последовательно выполняем такие команды:
mysql> CREATE DATABASE wordpressdb;
mysql> CREATE USER ‘wordpressdb_user’@’localhost’ IDENTIFIED BY ‘DbP@ssw0rd’;
mysql> GRANT ALL ON wordpressdb.* TO ‘wordpressdb_user’@’localhost’ IDENTIFIED BY ‘DbP@ssw0rd’;
Итак, мы создали БД wordpressdb и дали на нее полные права пользователю wordpressdb_user.
Следующий этап — создание отдельного сайта на IIS. Создадим новый каталог (например, с именем MyWordPress) в папке C:\inetpub\wwwroot\ .
Качаем архив с последней версией WordPress с этой страницы https://wordpress.org/download/ (на момент написания статьи это WordPress 4.0) и распаковываем его содержимое в каталог C:\inetpub\wwwroot\MyWordPress.
Откроем консоль управления IIS (Internet Informations Services Manager — C:\WINDOWS\system32\inetsrv\iis.msc) и щелкнув по разделу Sites, выберем Add Website.

Затем в консоли перейдем на созданный сайт (MySitePress) и дважды щелкнем по пункту Authentication.
В разделе аутентификации выберем пункт Anonymous Authentication и в панели Actions нажмите Edit..
В открывшемся окне изменить настройку на Application Pool Identity.
Далее предоставим нашему пулу приложения права записи на каталог, в котором находится сайт WordPress. Сделать это можно командой:
icacls «C:\inetpub\wwwroot\MyWordPress» /grant «IIS APPPOOL\MySitePress»:(OI)(CI)(RX,W)
Итак, мы настроили IIS, и можно переходить непосредственно к установке «движка» WordPress.
Откроем наш сайт в браузере ( http://localhost:8080 ) В открывшемся окне заполним параметры подключения к БД:
Database name : wordpressdb
Database username : wordpressdb_user
Database password : DbP@ssw0rd
Database host : localhost
Table prefix : mywp_ (префикс в общем-то произвольный и нужен, если в дальнейшем в этой же базе будут находится таблицы других сайтов WordPress )
После этого должно открыться окно, аналогичное представленному на 3 скриншоте. Далее все по аналогии.
- Для ускорения выполнения скриптов PHP в IIS рекомендуется установить специальный модуль-акселератор – Windows Cache Extension (или аналог)
- Для формирования SEO-friendly URL адресов нужно установить модуль IIS URL Rewrite
Бетке Сергей: iT блог
Web сервер для WordPress на Windows 2012 R2: настраиваем и оптимизируем

IIS7 уже имеем на базе Windows Web Server 2012 R2. Качаю Web Platform Installer. Далее по видео-инструкции всё устанавливаю – работает! Да, автоматизация просто на высоте, благодарности Microsoft.
Для Web сервера оптимально, безусловно, использовать виртуальный сервер (благо имею лицензию на MS Windows Server 2012 R2 Datacenter, посему могу себе позволить произвольное количество виртуальных машин). Но при конфигурировании сервера следует задумываться над последствиями каждого шага.
MySQL Server
MySQL Server data диск
И первый шаг, над которым следует хорошо подумать, – виртуальные диски. Не стоит размещать на системном диске и базы данных MySQL, и каталоги приложений IIS. Настойчиво рекомендую Вам подключить отдельный виртуальный диск, отформатированный в NTFS, для размещения баз MySQL. Объяснения простые – MySQL при закрытии транзакций сбрасывает кеш диска, на котором размещены его базы (что можно изменить параметром innodb_flush_log_at_trx_commit, но делать это небезопасно с точки зрения сохранения целостности базы данных). Чтобы выбор значения данного параметра не влиял на производительность ОС – перенесите каталог баз данных MySQL на отдельный (от системного) диск (в случае виртуальной машины – виртуальный диск). Ниже – цитата из my.ini:
Останавливаем службу MySQL сервера, вносим изменения в my.ini, переносим указанный выше каталог с системного диска на новый диск, запускаем службу.
Управление сервером MySQL
Да, всё можно сделать через консоль mysql, однако куда нагляднее и удобнее использовать для целей администрирования MySQL Workbench. Загружаем его с сайта, устанавливаем, запускаем.
Технологии подключения: TCP/IP vs Named Pipe
Собственно MySQL Server предлагает нам три “протокола” связи:
- shared memory (только в пределах одной рабочей станции);
- named pipe
- tcp/ip
“Родной” клиент mysql так же поддерживает все три протокола. Безусловно очевидно, что в среде windows протоколы приведены выше в порядке убывания производительности, и наиболее оптимальным для взаимодействия с локальный MySQL сервером был бы протокол shared memory. Однако php плагины на сегодняшний день не могут использовать shared memory для работы с MySQL. А жаль.
Вторым по производительности будет использование именованных каналов – named pipes. Доказывать смысла не вижу, в интернете можно найти массу обзоров. Основной аргумент – при использовании именованных каналов на одной станции ОС самостоятельно выбирает транспорт отличный от сетевого транспорта – собственно shared memory и выбирает. Посему производительность именованных каналов в случае локально расположенного MySQL сервера будет выше, и при удалённо расположенном – не ниже. (P.S. Возможно по этой причине разработчики PHP и не предложили явного использования протокола shared memory, предоставив при этом возможность использования named pipes). Стоит почитать и иные мнения: при сетевом взаимодействии tcp/ip будет быстрее (канал не передаёт данные, пока приёмник их не запросит, а в tcp/ip несколько иначе – приёмника никто не спрашивает, посылают и ожидают подтверждения). Итого, моё мнение: при локальной установке MySQL Server по отношению к IIS/PHP – выбирайте named pipes (не даром PHP по умолчанию пытается использовать named pipes), при удалённой установке – явно настраивайте TCP/IP подключение.
Опять цитата my.ini :
Я явно запретил использование сетевых протоколов моему экземпляру MySQL Server’а. В php.ini параметры подключения к БД выглядят следующим образом:
Использование «.» вместо localhost существенно!
P.S. Установка параметра default_socket в MySQL (значение по умолчанию) приводит к невозможности подключения, поэтому единственно правильно указывать default_host , как указано выше.
Ниже цитирую wp_config.php в части настроек подключения к БД:
Как видно, DB_HOST читаю из php.ini с расчётом на то, что MySQL сервер для всех php сайтов на данном веб-сервере один. Такой вариант существенно гибче в случае эксплуатации нескольких сайтов на одном сервере – настройки подключения правим в php.ini , и они действуют на все сайты.
Кратко итоги: на моём тестовом wordpress блоге время отдачи главной страницы сократилось с 410 мс в среднем до 390 мс при переходе с TCP/IP на named pipes (при локальном расположении сервера). Безусловно – при прочих равных условиях и при отсутствии промежуточных кэширующих серверов.
Charset и Collation
Естественно, целесообразно указать и кодовую таблицу для символьных данных, и правила их сравнения / сортировки. Достаточно подробное описание для MySQL нашёл на просторах сети — http://gahcep.github.io/blog/2013/01/05/mysql-utf8/. Итак, цитаты файлов конфигурации:
- Цитата wp_config.php :
- Цитата из my.ini :
- В php.ini параметры подключения к БД выглядят следующим образом:
Рекомендую использовать utf8_unicode_ci вместо utf8_general_ci , хотя он и более медленный, зато сюрпризов не будет, все правила сравнения и сортировки будут работать так, как ожидается.
P.S. lc-messages к этому разделу имеет далёкое отношение, но привести решил его здесь. Всё-таки приятнее видеть ошибки от MySQL на русском языке, нежели на каком-либо чужом.
MyISAM vs InnoDB
Общеизвестно, что MySQL “из коробки” поддерживает два движка БД – InnoDB и MyISAM. Начиная с версии 5.5 движком по умолчанию является InnoDB. Обзоры и обоснование выбора того или иного движка для WordPress доступны в сети, но они неоднозначны:
Да, многие хостеры выбора не предлагают – навязывают MyISAM вследствие невысокой потребности в памяти. Однако, для меня ключевым моментом стала поддержка кэширования данных со стороны InnoDB (MyISAM кэширует только индексы). Да, InnoDB поддерживает транзакции и блокировки на уровне записей (а не таблиц в целом), но для меня эти факты не являются значимыми – wordpress 99% запросов на чтение (если не больше), на запись – только мои запросы из консоли администратора, а я могу и подождать. А вот кэширование данных, что крайне положительно сказывается на выполнении банальных выборок, более чем полезно. Поэтому я выбираю InnoDB (ниже цитата из my.ini):
Но этого недостаточно!
Кроме того, что первые версии блога функционировали на более ранних версиях MySQL, поэтому таблицы базы созданы с движком MyISAM. Посему необходимо на живой базе изменить движок для таблиц. Для конвертации воспользуемся SQL сценарием, который я запущу из MySQL Workbench, но его с тем же успехом можно запустить и из mysql :
Итак, SQL код, приведённый выше, успешно меняет движок всех таблиц базы на InnoDB. При использовании MyISAM среднее время формирования главной страницы блога составило 390 мс. Однако, и после перехода на InnoDB (с настройками по умолчанию) время ответа то же — 390 мс. Следует разобраться с параметрами кэширования данных в InnoDB.
Некоторые рекомендации по реконфигурированию MySQL при переходе на InnoDB приведены на официальном сайте. Уменьшаем буфер для MyISAM ( key_buffer_size ) и увеличиваем буфер для InnoDB ( innodb_buffer_pool_size ) с учётом того, что InnoDB кэширует не только индексы, но и данные. В итоге, в my.ini внёс следующие изменения:
На этом с выбором и настройкой собственно движка пока закончим. Посмотрим, что нам сообщает сам MySQL в своих журналах.
Отлавливаем неоптимизированные медленные запросы wordpress
В каталоге данных (в моём случае – “I:\ProgramData\MySQL\MySQL Server 5.6\data”) MySQL сохраняет крайне полезный файл — %COMPUTERNAME%-slow.log . Останавливаем MySQL, удаляем / переименовываем имеющийся файл, запускаем MySQL и пытаемся воспользоваться нашим тестовым блогом. В результате вижу в этом файле:
В этот журнал, как уже понятно из его названия, MySQL записывает “медленные” запросы. В частности – запросы с отбором / сортировкой / объединениями без индексов. Как видно, в моём случае таких запросов оказалось 4. P.S. Блог “вырос” ещё с wordpress 3.0, возможно – проблемы со структурой таблиц связаны именно с этим, но решать то их всё равно нужно!
Итак, исправим таблицы (добавим индексы). В случае с wp_options индексов будет мало. Не могу объяснить решение разработчиков wordpress по применению типа varchar(10) для поля, по которому осуществляется отбор, и которое на самом деле имеет только два значения — ’yes и ’no’ . Даже применение индекса в этом случае приведёт к приличному числу сравнений unicode строк по достаточно сложным правилам! Посему решил изменить типа поля autoload на ENUM( ‘yes’, ‘no’ ) . Подобная замена типа пройдёт совершенно прозрачно для wordpress (запросы будут выполняться, как и раньше), но при этом глубина индекса – 1!
Таблица wp_wpo_campaign – наследство плагина WP-o-Matic. Там записей в моём случае всего 2!, но запрос, естественно, выполняется без индексов! Однозначно напрашивается поле nextactive вместо выражения в фильтре. Вероятнее всего, этот плагин я просто отключу. В любом случае при каждом обращении к сайту этот запрос мне просто не нужен!
Таблица wp_dynamic_widgets – наследство плагина Dynamic Widgets. Отказываюсь от его использования. Таблица явно не оптимизирована под фильтры, и оптимизация приведёт к изменению самих запросов.
Также целесообразно отказаться от плагина Redirection в пользу URL Rewrite на IIS или .htaccess на Apache. Данный плагин генерирует запросы при каждом обращении, причём, несмотря на наличие всех необходимых индексов, план выполнения запроса приводит к операциям без использования индексов (join трёх таблиц в одном запросе). Я пока не отказался от него, послежу ещё за его запросами.
Сценарий для оптимизации БД в моём случае выглядит так:
После его исполнения в журнале медленных запросов MySQL появляется только первый запрос (по wp_options ), и только при при первом запросе к БД. Итого — проблема медленных запросов решена. В итоге указанных выше небольших оптимизаций время генерации главной страницы сократилось с 390 до 330 мс!
Прочие мелочи
Приведу пару полезных ссылок при работе с MySQL:
MySQL и альтернативы: а можно ли быстрее?
Существуют альтернативные серверы БД, построенные на базе открытого кода MySQL. На Windows доступна только одна альтернатива — MariaDB. Качаю дистрибутив под Windows (есть msi пакет, что удобно). Скачал дистрибутив, запустил установку. Выбираем тип установки – обновление установленного экземпляра сервера БД. И обновление пройдёт полностью в автоматизированном режиме. При этом обновится и существующая служба MySQL Server. Замену произвёл ради более производительного движка вместо InnoDB – XtraDB.
В общем – рекомендую использовать MariaDB вместо MySQL с движком XtraDB. Однако, существенной разницы для wordpress я не заметил – порядка 30 мс отыграли.
А можно ли ещё быстрее? Кэшируем PHP код
Windows Cache Extension for PHP
P.S> Этот раздел можно сразу пропустить и перейти к следующему – альтернативному решению.
С увеличением объёма PHP кода (в том числе – и за счёт многочисленных плагинов) неизбежно возникают затраты на собственно интерпретацию PHP при каждом запросе. Но и здесь возможно кэширование. Для этих целей сообщество предлагает нам Windows Cache Extension 1.3 for PHP. Качаем его и устанавливаем. Настоятельно рекомендую Вам установить данное расширение к PHP.
Я поступил следующим образом:
- скопировал php_wincache.dll в C:\Program Files (x86)\PHP\v5.5\ext ;
- в php.ini дописал:
- и добавил файл reroute.ini дописал:
При включенном wincache.ocenabled минимум 100 мс мы выигрываем даже для PHP 5.5.
Родной OpCache
Но! В PHP 5.4+ есть встроенный оптимизатор (кэш) кода, но по умолчанию он выключен. И для него так же есть масса параметров, мой вариант для php.ini:
На этом с оптимизацией среды исполнения заканчиваю. И пора заняться кэшированием (http cache-control заголовки)













