Обновить
288
Юрий Насретдинов@youROCK

Программист, в основном на Go

167
Подписчики
Отправить сообщение

Перезапуск демона на PHP без потери соединений к нему

Время на прочтение13 мин
Охват и читатели20K
На различных конференциях мы неоднократно рассказывали про наше облако для CLI-скриптов (видеозапись доклада, слайды). Облако предназначено для того, чтобы запускать различные PHP-скрипты по расписанию или через API. Как правило, эти скрипты обрабатывают очереди, и нагрузка «размазывается» приблизительно по 100 серверам. Ранее мы акцентировали внимание на том, как реализована управляющая логика, которая отвечает за равномерное распределение нагрузки по такому количеству серверов и генерацию заданий по расписанию. Но, помимо этого, нам потребовалось написать демон, который был бы способен запускать наши PHP-скрипты в CLI и следить за статусом их исполнения.

Изначально он был написан на Си, как и все остальные демоны в нашей компании. Однако мы столкнулись с тем, что существенная часть процессорного времени (около 10%) тратилась, по сути, впустую: это запуск интерпретатора и загрузка «ядра» нашего фреймворка. Поэтому, чтобы иметь возможность инициализировать интерпретатор и наш фреймворк только один раз, было принято решение переписать демон на PHP. Мы назвали его Phprocksyd (по аналогии с Phproxyd — PHP Proxy Daemon, демоном на Си, который у нас был до этого). Он принимает запросы на запуск отдельных классов и делает fork() на каждый запрос, а также умеет сообщать о статусе исполнения каждого из запусков. Такая архитектура во многом похожа на модель веб-сервера Apache, когда вся инициализация делается один раз в «мастере» и «дети» занимаются уже именно обработкой запроса. В качестве дополнительной «плюшки» мы получаем возможность включить opcode cache в CLI, который будет правильно работать, поскольку все дети наследуют ту же область общей памяти, что и мастер-процесс. Чтобы уменьшить задержки при обработке запроса на запуск, можно делать fork() заранее (prefork-модель), но в нашем случае задержки на fork() составляют около 1 мс, что нас вполне устраивает.
Читать дальше →

Badoo PHP Code Formatter. Теперь в open source!

Время на прочтение13 мин
Охват и читатели28K
Несколько лет назад компания Badoo начала значительно расти по числу сотрудников, с 20 до 100 и более. Это потребовало серьезной перестройки многих процессов, касающихся разработки. Одна из проблем, с которой мы столкнулись, — как заставить всех разработчиков следовать единому стандарту кодирования, чтобы весь наш код выглядел единообразно и был легко поддерживаемым?

Для решения этой задачи мы решили внедрить инструмент для форматирования кода, который умел бы следующее:

  1. выводить сообщения о несоответствии стандарту форматирования в виде списка, не трогая сам файл;
  2. автоматически исправлять все найденные проблемы с форматированием;
  3. уметь форматировать только часть файла (нам не нужно переформатировать репозиторий сразу целиком, чтобы не потерять историю).

Мы рассматривали два проекта, которые можно было бы взять за основу для написания такого инструмента — PHP Beautifier и PHP Code Sniffer. Первый умел форматировать код, но не умел печатать диагностику, а второй — наоборот, умел печатать диагностику, но не умел форматировать файлы. К сожалению, оба этих проекта, по нашей оценке, были не слишком пригодны для того, чтобы добавить в них недостающую нам функциональность, поэтому была написана новая утилита — phpcf (PHP Code Formatter). Уже в течение двух лет она работает как git pre-receive hook, настроенный на отклонение (!) изменений, которые не оформлены по нашему стандарту кодирования.

Наконец настало время открыть исходные тексты нашей утилиты для широкой публики: github.com/badoo/phpcf
Читать дальше →

Переход на PHP 5.5 и юнит-тесты

Время на прочтение4 мин
Охват и читатели19K
С момента перехода с PHP 4.4 на PHP 5.3 в Badoo прошло уже 4 года, пришла пора обновлять PHP, на этот раз сразу на версию PHP 5.5. Помимо новых фич, новая версия PHP в очередной раз принесла нам существенное увеличение производительности, поэтому у нас было много причин для апгрейда. В этой статье мы расскажем о том, как мы переходили на PHP 5.5, какие «грабли» собрали, и зачем в очередной раз переписывали нашу систему для запуска юнит-тестов на основе PHPUnit.


Рис 1. Общая архитектура

«Грабли» при переходе с PHP 5.3 на PHP 5.5


В прошлый раз мы переходили с четвертой версии PHP на пятую, причём наша версия PHP 5.3 содержала патчи, чтобы работал «старый» синтаксис PHP, например, $a = &new ClassName();, и чтобы наша кодовая база могла работать на PHP4 и PHP5 одновременно. На этот раз у нас таких ограничений не было, поэтому при переходе мы просто нашли и заменили все устаревшие конструкции на более актуальные, и на этом переписывание кода было закончено.

Основные проблемы, которые у нас возникли:
  • часть deprecated-фич языка была убрана;
  • расширение mysql стало deprecated;
  • низкая производительность расширения runkit, которое мы используем при написании юнит-тестов.


После перехода на PHP 5.5 наши юнит-тесты начали проходить значительно дольше (в несколько раз), поэтому мы решили в очередной раз доработать нашу «пускалку», чтобы решить эту проблему.

Читать дальше →

Исполнение SSH-команд на сотнях серверов с помощью Go

Время на прочтение5 мин
Охват и читатели38K

О чём статья


В этой статье мы с вами напишем простенькую программу на Go (в 100 строк), которая может исполнять команды через протокол SSH на сотнях серверов, делая это достаточно эффективно. Программа будет реализована с помощью go.crypto/ssh — реализации SSH протокола авторами Go.

Более «продвинутая» версия программы, написанной в этой статье, доступна на гитхабе под названием GoSSHa (Go SSH agent).
Читать дальше →

Подходы к оптимизации (веб-)приложений

Время на прочтение8 мин
Охват и читатели32K
Не знаю, как вы, я лично обожаю заниматься оптимизацией производительности программ. Я люблю, когда программы не тормозят, а сайты открываются быстро. В этой статье я бы хотел привести некоторые (базовые) подходы к улучшению производительности. В основном, они относятся к веб-приложениям, но некоторые вещи справедливы и для «обычных» программ. Я затрону такие темы, как профилирование, пакетная обработка, асинхронная обработка запросов и др. Этот топик можно считать продолжением «Стратегии оптимизации веб-приложений с использованием MySQL.
Читать дальше →

Удобная работа в консоли, или красим STDERR в красный цвет

Время на прочтение7 мин
Охват и читатели21K

Работа в консоли


Многие из нас пользуются консолью каждый день, и, наверное, каждый задавал себе вопрос: как я могу сделать свою работу в консоли эффективнее? Что я могу сделать, чтобы тратить меньше времени на выполнение рутинных операций? В этой статье я бы хотел вкратце рассказать о нескольких простых, но полезных вещах при работе с bash, о которых вы, возможно, не знали.
Читать дальше →

Автоматизированный рефакторинг в большом проекте

Время на прочтение19 мин
Охват и читатели18K
Если вы работаете в большой команде разработчиков над одним и тем же проектом, то рефакторинг становится очень сложной задачей. Приведем пример: мы хотим переименовать функцию do_something() в do_something_with_blackjack(). Мы переименовали все вхождения этой функции в своей ветке и отправили задачу на тестирование. В тот же момент кто-то другой добавил ещё один вызов функции, но со старым названием, тоже в своей ветке. По отдельности наборы изменений будут работать, а вот после слияния получится ошибка.

В статье будет рассмотрен приём, который можно назвать «автоматизированный рефакторинг» — использование самописных скриптов, которые делают нужную работу за вас, позволяя провести рефакторинг после слияния всех веток и перед непосредственной выкладкой на staging/production.

На примере phpBB будет показано, как можно «отрефакторить» вызовы SQL-запросов, чтобы они использовали автоматическое экранирование входных данных (и таким образом помочь в решении проблемы SQL-инъекций).
Читать дальше →

Слежение за изменениями в директории: как это делается в разных ОС

Время на прочтение3 мин
Охват и читатели77K
Я бы хотел посвятить статью обзору API, предоставляемых разными ОС для слежения за изменениями в директории. Статья появилась как результат моей работы над демонами слежения за изменениями для утилиты dklab_realsync (статья на хабре, github репозиторий) и своей собственной, которую я пока что не хочу анонсировать.
Читать дальше →

Внутреннее устройство Git: хранение данных и merge

Время на прочтение9 мин
Охват и читатели96K
В процессе перехода с SVN на Git мы столкнулись с необходимостью переписывания наших внутренних инструментов, связанных с развёртыванием кода, которые ориентировались на существование линейной истории правок (и разработку в trunk). На Хабре уже публиковались возможные решения этой проблемы через Git-SVN, но мы пошли другим путём. Нам нужна поддержка таких возможностей Git, как branching и merge, поэтому мы решили разобраться в основах, как же работает Git и каким способом должна осуществляться интеграция с ним.
Читать дальше →

Надежный код при высоких нагрузках

Время на прочтение6 мин
Охват и читатели38K
Когда речь идет о высоких нагрузках, как правило, в центре внимания оказываются вопросы производительности или масштабируемости кода и архитектуры.

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

Написание программ на PHP с использованием fork()

Время на прочтение5 мин
Охват и читатели39K

Параллельные программы на PHP


Раньше заголовок темы был «Написание многопоточных программ на PHP». В PHP есть ровно один «нормальный» способ писать приложения, которые используют несколько ядер/процессоров — это fork(). О прикладном использовании системного вызова fork() в языке PHP и расширения pcntl я и расскажу. В качестве примера мы напишем достаточно быструю параллельную реализацию grep (со скоростью работы, аналогичной find . -type f -print0 | xargs -0 -P $NUM_PROCS grep $EXPR).
Читать дальше →

История одного файлового менеджера

Время на прочтение14 мин
Охват и читатели6.8K
Не знаю, как вы, а я начинал изучение веба и PHP в частности путём написания бесплатных скриптов. Я написал 2 своих CMS, галерею, форум, гостевую книгу… Первым моим проектом был файловый менеджер, и бы хотел рассказать о том, через какие стадии развития он прошел и чем стал в итоге. Например, я научил его открывать папки с 500к файлов, не вылезая за memory_limit в 32 Мб с временем генерации страницы в несколько секунд.

Я подготовил небольшое демо его работы, а также выложил исходники файлового менеджера на github. Исходные тексты не слишком высокого качества, ибо в основном писалось это мной году в 2007, то есть 5 лет назад :).
Так как оно открывает 100500 файлов?

Пишем веб-эмулятор терминала на Go, используя Websocket

Время на прочтение5 мин
Охват и читатели7.5K

Что будем писать


В прошлой статье мы писали простенький эмулятор терминала на PHP. Я думаю, теперь время написать что-нибудь более серьезное, на вебсокетах. Какой язык использовать для работы с вебсокетами..? Питон..? Руби..? JavaScript..? Нет! Раз уж зарелизился Go 1, давайте на нём и напишем ;). Я постараюсь не повторяться и не писать сюда целиком код. Я приведу лишь интересные, на моей взгляд, фрагменты.

Демо


Спасибо пользователю Aleks_ja за возможность посмотреть эмулятор терминала в действии (нужен браузер с последней версией вебсокетов — например это Firefox 11 или последний Chrome). С первого раза оно может не подключиться, если демон не успеет стартовать за 100 мс — попробуйте сначала обновить страницу.



Исходный код веб-терминала доступен на гитхабе. Компилировать вебсокет-демон необходимо самостоятельно (командой go build) — это небольшая мера защиты от тех, кто любит «повзламывать» хостеров ;).
Читать дальше →

Пишем простенький веб-эмулятор терминала на PHP

Время на прочтение6 мин
Охват и читатели19K
Я думаю, очень много людей думало над тем, чтобы сделать свой эмулятор терминала на PHP, и обычно останавливались на решениях вроде следующего:
<?php echo '<form><input name="cmd" /></form>'; if(isset($_GET['cmd'])) system($_GET['cmd']);

Конечно же, такое решение вызывает целый набор проблем, самая незначительная из которых — это то, что ошибки на экран не попадают. Есть и намного более значительные вещи, например запуск vi просто «подвесит» выполнение команды и придется открывать новую консоль и писать killall vi. И что уж точно не получится сделать, так это выполнить команды ssh или sudo, которые требуют чтения пароля прямо с терминала. Я постараюсь показать способ, с помощью которого можно устранить большую часть описанных выше проблем.
Читать дальше →

Исследуем прародителей Minecraft: Dungeon Keeper

Время на прочтение3 мин
Охват и читатели3.4K
Я думаю, что о Minecraft слышали почти все. Но, возможно, не все видели одну из замечательных игр, из которой Нотч брал свои идеи — я говорю Dungeon Keeper. Я не собираюсь пересказывать википедию насчет того, что из себя представляет игра, ибо, как мне кажется, лучше один раз увидеть, чем 100 раз услышать или прочитать ;).
Читать дальше →

«Правильный» system() для PHP-CLI

Время на прочтение2 мин
Охват и читатели14K
Внимание! Все рассуждения относятся к запуску PHP в режиме CLI, а не как модуль веб-сервера!

Если вы когда-либо использовали функцию system() в PHP, вы наверняка задавались вопросом: каким образом system() возвращает последнюю строку для команды, да ещё и выводит результаты исполнения команды на веб-страницу, а не себе куда-то в stdout веб-сервера? И почему system() работает не так, как system() в Си? Ответ, в общем-то, проще, чем может показаться.
Читать дальше →

Стратегия оптимизации веб-проекта с использованием MySQL

Время на прочтение5 мин
Охват и читатели8.4K

Введение


В жизни любого крупного веб-проекта, особенно на PHP, но, в целом, это касается любого серверного ЯП, пригодного для веб-разработки, обычно наступает понимание, что «так дальше жить нельзя», и что настал момент, когда нужно провести оптимизацию работы сайта, чтобы он перестал тормозить (хотя бы на production).

Интересно, что, как правило, даже тяжелые фреймворки (вроде Symfony или RoR) на «медленных» языках, в production-окружении работают достаточно сносно по скорости, а основные «тормоза» вызываются SQL-запросами и неграмотным кешированием (к примеру, инициализация достаточно сложной и большой конфигурации проекта на Symfony занимает около 80 мс, а времена исполнения страницы, при этом, иногда достигают секунды и более).

Если вы смогли определить, что это — ваш случай, и ваш проект на MySQL, то эта статья может вам помочь принять конкретные меры и исправлению ситуации с закреплением результата и предотвращением возникновения откровенных проблем с СУБД впоследствии.
Читать дальше →

Читаем (и пишем) MyISAM напрямую

Время на прочтение5 мин
Охват и читатели13K
В недрах документации MySQL на dev.mysql.com я как-то обнаружил упоминание о том, что в случае, если используется MyISAM, можно получить прирост в скорости чтения из таблицы в 5-7 раз, если читать данные из таблицы самостоятельно. Мне довольно долго хотелось проверить этот факт и вот, наконец, у меня дошли руки до того, чтобы это попробовать. Что из этого вышло, читайте под катом
Читать дальше →

Отличие Javascript от PHP

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

В статье я хотел бы рассказать о некоторых прикольных моментах, с которыми может столкнуться разработчик на каком-нибудь динамическом языке, когда увидит PHP, или наоборот, разработчик на PHP, когда будет изучать какие-то другие динамические языки. Статические языки я не рассматриваю, ибо там вроде как всё итак понятно.
Читать дальше →

Исследуем производительность JOIN в MySQL

Время на прочтение4 мин
Охват и читатели39K
Я думаю, ни для кого не секрет, что JOIN считается достаточно дорогой операцией, и многих начинающих программистов (которые юзают MySQL) любят запугивать, что JOIN — это плохо, и лучше всего обойтись без них, если есть возможность.

Давайте исследуем этот вопрос более подробно и посмотрим, действительно ли JOIN — это плохо, и когда вообще стоит задумываться об этом.
Читать дальше →

Информация

В рейтинге
Не участвует
Откуда
London, England - London, Великобритания
Дата рождения
Зарегистрирован
Активность