Jul 11

Некоторые свои посты я дополняю постами-линками на Хабрахабре. Последний подобный пост - “Особенности работы jQuery.live()“. Он так и не попал на главную, но в данном случае это не очень важно, т.к. свой “хабраэффект” я поймал.

До этого у меня случались странности на сервере - он начинал есть все 400% процессора и наглухо зависал - к нему было невозможно подключиться и единственным вариантом восстановления был шатдаун инстанса в админке Linode. Это случалось нечасто и не особо меня парило. Но когда на мой сайт стали постоянно заходить люди с хабра - такое поведение сервера стало постоянным. Он начинал есть весь процессор. После перезагрузки он пару минут держался, а потом опять начинал свой бравое дело. Стало ясно - что-то явно не так в настройках.

После довольно недолгих разбирательств стало ясно, что виноват Apache (у меня стоит Apache + mod_prefork + php + ruby via passenger). Параметры prefork-а:

<IfModule mpm_prefork_module>
StartServers          5
MinSpareServers       5
MaxSpareServers      10
MaxClients          150
MaxRequestsPerChild   0
</IfModule>

Теперь мне стало очевидно всё, кроме одной вещи - почему же все-таки был загружен процессор… А причина зависаний сервера была проста - параметр MaxClients отвечает за то, сколько процессов апач может запустить для обработки пользователей (в prefork-е каждый запрос обрабатывается отдельным процессом, который либо запускается, либо вытаскивается из пула свободных запущенных процессов). Процессы апача ну очень недешевые в плане ресурсов - честно говоря, я до сих пор не знаю, как можно посмотреть, сколько реально кушает процесс апача - по текущей нагрузке на сервак при создании новых процессов апач кушает лишние 10-20мб памяти. 150 процессов * 10 мегабайт… Ну вы поняли. У меня сейчас обычныя VPS-ка на 360Мб. В общем, причина зависаний была в том, что апач создавал кучу процессов и уходит в своп по самое нехочу. А вот вернуться оттуда он уже сам не мог - ему нужна была помощь.

Выход - снижать количество максимально процессов апача. Методом научного тыка была выбрана цифра в 20 процессов. Собственно, сейчас эта цифра вполне себе хорошо работает. После уменьшения MaxClients и перезапуска сервера он падать перестал. Но появилась новая проблема - из-за хабраэффекта сервак хоть и не падал, но  отдавал ответы очень долго. Эту проблему я решил не решать, т.к. в тот момент был на работе. Сейчас вот появилось немного времени и я решил протестировать свой блог на отзывчивость.

ab -c 1 -n 100 http://blog.fxposter.org/

Эмм… Результата я не дождался.

Для тех, кто не работал с ab и не знает, что это такое - Apache Benchmark.

ab -c 1 -n 10 http://blog.fxposter.org/

Результат меня неприятно удивил. Результаты, к сожалению, не сохранились, но могу сказать точно, что время генерации страницы было около 1.5 секунды (судя по тому, что сейчас показывает генерация страницы, если её нет в кеше).

Собственно, стало понятно, как бороть “хабраэффект” - нужно сильно ускорить отдачу странички. Как? Да очень просто - кешированием. Слава богу, что это WordPress и тут есть такие плагины, как wp-cache - прикручивается за несколько минут и пока что отлично работает. Если бы такого плагина не было, то, наверное, у меня бы была сейчас статья о том, что такое Reverse Proxy и как его использовать для кеширования. :) А так - поставил, включил. Результаты:

Заодно решил немного пооптимизировать клиентскую часть - добавить expires и сжатие контента (использовался модуль апача deflate).

Приведу конечные файлы:

# /etc/apache2/mods-available/expires.conf
<IfModule mod_expires.c>

ExpiresActive On

ExpiresByType image/gif "access plus 1 weeks"
ExpiresByType image/png "access plus 1 weeks"
ExpiresByType image/jpeg "access plus 1 weeks"

ExpiresByType text/css "access plus 1 weeks"
ExpiresByType application/javascript "access plus 1 weeks"
</IfModule>
# cat /etc/apache2/mods-available/deflate.conf
<IfModule mod_deflate.c>
 # AddOutputFilterByType DEFLATE text/html text/plain text/xml

 DeflateCompressionLevel 9

 # Insert filter
 SetOutputFilter DEFLATE

 # Netscape 4.x has some problems...
 BrowserMatch ^Mozilla/4 gzip-only-text/html

 # Netscape 4.06-4.08 have some more problems
 BrowserMatch ^Mozilla/4\.0[678] no-gzip

 # MSIE masquerades as Netscape, but it is fine
 # BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

 # NOTE: Due to a bug in mod_setenvif up to Apache 2.0.48
 # the above regex won't work. You can use the following
 # workaround to get the desired effect:
 BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html

 # Don't compress images
 SetEnvIfNoCase Request_URI \
 \.(?:gif|jpe?g|png)$ no-gzip dont-vary

 <IfModule mod_headers.c>
 # Make sure proxies don't deliver the wrong content
 Header append Vary User-Agent env=!dont-vary
 </IfModule>
</IfModule>

Если вас интересует, почему эти файлы выглядят именно так - читайте документацию к модулям апача.

На другой ОС (у меня Ubuntu 9.04) эти файлы, наверняка, должны будут находиться в других местах. У себя я их разместил так, потому что эти конфиги автоматически подключаются вместе с подключением соответствующих модов апача (при использовании команды a2enmod).

По идее теперь сайт должен получше откликаться и, думаю, все-таки теперь он выдержит хабраэффект. :)

PS. С точки зрения клиентской оптимизации - css-ки и js-ки лучше бы собрать в один файл, а кучу запросов к изображениям заменить спрайтами. Заниматься первым особо не вижу смысла, т.к. и стилей и скриптов на блоге немного, а изображениями заниматься лень, т.к. все равно собираюсь переезжать на “Twenty Ten“.

written by fxposter \\ tags: , , , , ,

Jul 16

Последней каплей на предыдущем хостинге стало то, что я WordPress обновлял больше часа по FTP. И всё из-за этих самых разрывов. В общем - сбэкапил я оттуда весь контент и бд, перенаправил NS’ы домена на Dreamhost, а сегодня утром поставил WP на новый хостинг, залил базу, попутно переведя её в UTF-8, и теперь наслаждаюсь жизнью.

PS. По-моему теперь блог стал грузиться быстрее. :)

written by fxposter \\ tags: ,

May 19

Вдогонку к предыдущему посту. В первом же комментарии заметили, что править wp’шные исходники в общем случае нежелательно. В принципе и не “в общем” случае тоже нежелательно. :) Поэтому - исправляемся.

Теперь для решения проблемы из предыдущего поста достаточно скачать плагин (txt, zip).

written by fxposter \\ tags: , ,

May 18

Столкнулся с багом в WordPress’е при выводе постов, а точнее в “применении” к ним “типографики”:

wptexturize

Как видите, кавычки в некоторых словах расставлены абсолютно не так, как нужно. В поисках решения проблемы обнаружил следующее - в WordPress’е на каждый блок выходных данных, будь то заголовок, сам пост, его комментарии или что-либо еще, навешиваются фильтры, которые определенным образом изменяют блок - убирают теги, заменяют одни символы на другие и т. д.

В данном случае меня интересовал блок the_content (в данном случае понятие “блок” можно интерпретировать как “функция WP, которая возвращает некий контент”), который выводит содержимое поста. В файле wp-includes/default-filters.php можно увидеть, какие фильтры применяются к этому блоку:

add_filter('the_content', 'wptexturize');
add_filter('the_content', 'convert_smilies');
add_filter('the_content', 'convert_chars');
add_filter('the_content', 'wpautop');
add_filter('the_content', 'prepend_attachment');

Методом проб и ошибок было установлено, что найденный мной баг “создает” фильтр wptexturize (в WP “фильтр” - это функция, которая принимает 1 аргумент - входящий текст, и возвращает обработанный текст). Функция нашлась в файле wp-includes/formatting.php. Она выполняет “типографскую” работу, при этом пропуская всё, что находится между тегами pre, code, kbd, style и script. В теории… На практике - нихрена она не пропускает, если внутри одного из этих тегов будет какой-либо другой тег (что, в принципе, возможно, но встречается редко, а случай pre > code система хавает на ура), либо если внутри какого-нибудь из этих тегов встретится \[.*\] - вот такой кусок (у меня этим куском был ['comment_post_ID'], например). Почему так - не могу знать (мне вообще непонятно зачем наряду с тегами <.*> рассматривать еще и \[.*\]), но факт остается фактом. Улучшенная версия этого файла находится здесь (у меня WP 2.5.1, если что).

written by fxposter \\ tags: ,

May 18

Совершенно случайно обнаружил, что у меня нифига не работает WP’шный плагин Subscribe to Comments, хотя раньше проблем с ним вроде не было. Проверка того “что не так” и исправление этого всего у меня заняла добрые два часа…

Сначала грешил на WP 2.5, несовместимость таблиц и прочее - нифига, в бд всё, что нужно есть, но вот только сам факт подписки на комментарий туда заноситься не хотел ну вообще никак. Debug показал, что обработчику subscribe’ов вместо данных, введенных в форму коммента приходит “пустота” - абсолютно пустой $_POST. Глянув в строку адреса - обнаружил там длиннющую строку со всякими не сильно понятными значениями. Что ж, смотрим $_GET…

После просмотра, стало понятно, в чем затык - виной всему был OpenID-плагин, который для аутентификации пользователя выполнял всякие редиректы на другие сайты, после чего поток управления возвращался обратно в WP, однако все POST-данные оказывались потерянными. Нужные, по мнению OpenID-плагина, данные передавались теперь через GET, но OpenID, к сожалению, ничего не знал о плагине Subscribe to Comments и никаких данных о том, подписался ли пользователь на текущий пост, не передавал.

Решить проблему получилось с двух подходов. В первом я пытался сделать так, чтобы проверки OpenID выполнялись после того, как добавится подписка. После некоторых раздумий и просмотра того, как реализовывается подписка, стало понятно, что из этого способа ничего не выйдет. Поэтому пришлось лезть в исходники OpenID-плагина и искать то место, где создаются данные, хранимые в “сессии OpenID-аутентификации” и которые передаются обратно на сайт.

Довольно быстро это место нашлось - функция comment_tagging в файле logic.php:

$this->start_login( $openid_url, '/wp-login.php', 'commentopenid',
  array(
    'wordpressid' => $comment['comment_post_ID'],
    'redirect_to' => get_permalink( $comment['comment_post_ID'] ),
  )
);

Добавляем сюда нужные нам поля, а именно поле subscribe:

$this->start_login( $openid_url, '/wp-login.php', 'commentopenid',
  array(
    'wordpressid' => $comment['comment_post_ID'],
    'redirect_to' => get_permalink( $comment['comment_post_ID'] ),
    'subscribe'   => isset($_POST['subscribe']) ? $_POST['subscribe'] : null,
  )
);

После чего лезем в плагин Subscribe to Comments, находим функцию add_subscriber и меняем следующую строку:

if (($_POST['subscribe'] == 'subscribe' && is_email($email)) || $previously_subscribed) {

На такую:

if (($_REQUEST['subscribe'] == 'subscribe' && is_email($email)) || $previously_subscribed) {

После чего работоспособность подписки на комментарии восстановится.

PS. Так что, если вы задавали вопросы, подписались на комментарии и не получили ответа - зайдите на страничку поста - может быть я вам уже ответил. :)

written by fxposter \\ tags: ,

Dec 07

Сколько раз и на каком количестве блогов поднималась эта тема - не сосчитать. И все же я попробую поднять её еще разок. Я не собираюсь описывать кучи плагинов, нет. Я просто опишу те плагины, которые сейчас стоят у меня и попробую проанализировать их ценность на среднестатистическом блоге.

Пожалуй, начнем:

  • Akismet

    Чекалка комментариев на спам. Отлавливает спам достаточно хорошо, хотя иногда хотелось бы, чтобы она это делала получше. Для работы понадобится WordPress API Key. Этот плагин идет, если мне не изменяет память, в комплекте с WP, так что ничего ниоткуда дополнительно скачивать не прийдется. Включение, на мой взгляд, обязательно. Спама бывает много.

  • FeedBurner FeedSmith и Feed Locations

    Если вас устраивают возможности стандартного RSS-потока, который выдает по умолчанию WP -можете переходить к следующему пункту. Если же вы хотите получить кучу бонусов - регимся в FeedBurner и ставим эти плагины.

  • Get Recent Comments

    Выводит список последних комментариев. Еслихочется такую штуку, а ковырятся в кодах лень - можете поставить. Мое мнение - чисто на любителя.

  • Подсветка кода

    Если вы программист и хотя бы периодически пишете посты с включениями кода - рекоммендую обзавестись плагином, который этот самый код будет подсвечивать. Я использую Сагалаевский highlight.js. Есть еще CodeColorer от kpumuk’а и, думаю, еще куча разных плагинов в этой категории.

  • LiveJournal Crossposter

    Теперь меня могут читать и френдить ЖЖ’шники. Здесь все строго на любителя. Рекомендовать поставить этот плагин смысла особо не вижу. В категорию “необходимые” его отнести ну никак нельзя.

  • Now Reading

    Показывает книги, которые вы читали, читаете и собираетесь прочитать. Инфу берет с Амазона. Также строит некоторое подобие галереи всех ваших книг. Мне плагин нравится, только сейчас я вот никак не придумаю - куда бы выводить красиво хотя бы текущие книги…

  • One-Face Comments

    Я про One-Face писал… Решайте сами…

  • Recommended Tags и Tag Managing Thing

    Дополнения ко встроенным в WP >= 2.3 функциям тегов. Первая подбирает теги по тексту поста, вторая выводит список (облако) тегов под полем ввода поста для быстрого выбора нужных тегов. С одной стороны, плагины вроде как и нужные, с другой - они у меня работают, но пользуюсь ими я крайне редко, т.к. найти что-то в облаке тегов мне возможным не представляется, много у меня их слишком… :(

  • Subscribe To Comments

    Подписка на комментарии… На мой взгляд, один из самых нужных плагинов! Настоятельно рекоммендую!

  • Related Posts

    Недавно поставил у себя… Хочу вот спросить - а нужно ли оно?

  • WordPress Database Backup

    Читаем Gluek’а, понимаем, что бэкапы - это святое… И ставим плагин.

И вот хочу так ненавязчиво попросить всех - не ставьте себе плагин SnapShots, это он только на вид кажется очень удобным, на деле - жутко раздражает!

written by fxposter \\ tags:

May 30

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

Список всех нововведений, да и вообще, официальный релиз этой версии WP можете посмотреть здесь.

PS. У меня сегодня контрольная по культурологии, к которой я практически не готов. Пожелайте мне удачи.

written by fxposter \\ tags:

Mar 22

Вот такое название имеет движок, который претендует на звание WordPress-киллера. О нем я сегодня узнал из блога Slaff’а, хотя он и раньше намекал о нем.

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

Ну раз внутренняя обертка не впечатлила - решил полезть в коды, посмотреть, что там и как. Порадовало хорошее проектирование. Все на ООП, куча классов, всё красиво, в отличии от дизайна. Но так как slaff говорит, что дизайн будет еще переделан - есть надежда, что в итоге проект окажется хорошим, сейчас проект вообще еще в альфа версии.

Текущие недостатки, которые я тут выкопал:

  1. Глючит при включении mbstring вместо обычных функций работы со строками
  2. В админке - Manage -> Comments дает только approve’ить, что коммент не спам, редактирование или удаление комментов отсутствует как класс :)
  3. Опять же - в админке нельзя удалить пост, но тут хотя бы кнопка для этого есть (нерабочая она пока что)
  4. Зависит от темы, но все же - на главной странице нет ни одной ссылки на админку
    Хм… Щас форма логина появилась, но раньше ее 100% не было
  5. Разницы между Page и Post не уловил - либо пока что Page’ы вообще не пашут, либо тут что-то сильно глючит :)
  6. Справа висит непонятный текст, говорящий “About” - ну логично, страничка о себе. Проблема в том, что этот эбаут ссылкой не является :)
  7. Ну и т.д. тут много всего пока что править нужно… Надо у slaff’а узнать, как туда тестером устроится :)

Но не все так плохо - проект еще в альфа-версии, но он уже работает, им уже можно пользоваться (хоть и с очень большой натяжкой). Думаю, не-программисту будет в принцпе все равно, какой движок юзать. И если это действительно будет так - я, наверное, перейду на Хабари - написан он все-же красивее.

PS. Теперь бы выкопать где-нибудь хостинг с PHP5 и включенными PDO и PDO_MySQL…

written by fxposter \\ tags: , , ,

Feb 21

Вышел WordPress 2.1.1. Себе уже поставил. Особо отличий не заметил.

PS. Как оказалось - есть люди, которые так и не поняли, что ссылка “Меню” справа вверху там не просто так стоит, а еще и выполняет некоторые функции :)

PPS. Препод все-таки разрешил делать RSS ридер. Уговаривать пришлось долго, но разрешил :)

written by fxposter \\ tags:

Feb 04

Добавил у себя в блоге подсветку кода. Пример - мой предыдущий пост.

PS. Ивану Сагалаеву респект ;)

written by fxposter \\ tags: