Архив

7000 rps на Nginx - Achievement unlocked

Вчера, мой уютный сервачок подвергся очередному стресс тесту.

Для тех кто не в теме, у меня тут еще живет сайт и форум группы CENTR, а вчера в Питере проходил концерт HipHop All Stars 2012. Организаторы повели себя достаточно круто и предложили всем заинтересованным смотреть прямую трансляцию с концерта. Мы стали одним из проектов, которые на главной странице разместили флеш плеер, по которому велась трансляция. Что бы людям не было скучно, подключил еще и комментарии от Вконтакте.

Респект Вконтакту, в пиковые моменты комментарии в прямом эфире появлялись со скоростью 3-4 штуки в секунду. Всего за день на странице появилось примерно 15 000 комментариев.

Когда я вечером зашел посмотреть модные графики, то был приятно удивлен. Пиковая нагрузка на MySQL была примерно 3000 rpm, на Nginx ~8000 rps.

mysql

Cудя по логам, ни одного slow request не было, как и не было 404 и 50x страниц.

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


PHP Memoize

Вчера ради интереса пересматривал pecl каталог модулей для php, наткнулся на интересный модуль memoize. Вспомнил, что сам делал его реализацию на уровне php+memcached.

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

Так же нужно понимать, что код будет выполнен только один раз, поэтому использование, например, sql запросов в ф-ции не допустимо. Недопустимо использование global и его аналогов Static::$data, недопустимо использование ветвлений в зависимости от времени или окружения.

function my_expensive_function($x) {
    sleep(10);
    return $x . 'bar';
}

memoize('my_expensive_function');

// now calls to my_expensive_function() are cached by their arguments

echo my_expensive_function('foo'); // returns "foobar" in 10s
echo my_expensive_function('foo'); // returns "foobar" in 0.0001s

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


В уме

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

v-ume

В следующий раз, когда вы пройдете очередное обновление Angry Birds и полезете в AppStore в поисках новой убивалки времени, то вместо игрушек, поставьте себе это приложение. «В уме» — это сборник математических задач на устный счет. Задачи действительно интересные. И больше всего меня радует сам форм-фактор, да, это именно та игрушка с которой удобно работать, например, в транспорте. Нет нужды постоянно фокусироваться на экране, тут ничего не зависит от твоей ловкости и координации, только полезная разминка для мозгов.

v-ume

v-ume

Ссылка в AppStore.


Варианты загрузки

Меня добивает на некоторых сайтах страницы загрузки софта. Сегодня с утра скачивал новый релиз PhpStorm, обратите внимание на список.

phpstorm-download

Windows, Mac OS X, Unix, ZIP. ZIP!. Вот что там внутри? Под какую это платформу?

phpstorm-download

Внутри там, кстати, бинарники для windows


Вернемся к этому позже

Внезапно понял какой фичи мне не хватает в Gmail.

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

Некоторые решают эту проблему с помощью хитрой системы ярлыков, другие держат под рукой evernote или remember the milk, а мне лень отвлекаться и делать столько действий, просто чтобы не забыть, уж лучше запомнить, реально.

Мне нужна простая кнопка, которая позволяет отметить письмо как прочитанное, а через 6 или 12 часов сделает его снова не прочитанным, а потом я смогу еще раз ее нажать и в итоге я не буду отвлекаться на новые письма, никогда не потеряю их в груде других вещей и отреагирую, когда будет время или посчитаю это нужным.

Реально, эта фича спасла бы мир.


Failed to validate oauth signature and token

На досуге, решил навоять один сервис, который тесно интегрирован с социальными сетями, в частности с твиттером. Во время работы, натолкнулся на интересную ошибку, в "некоторый момент", апи твиттера вылетает и начинает на любые запросы отдавать 401 ошибку. Не авторизован ты и все.

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

Тихо и не спеша, я просрал на это дело около трех вечеров, по 1-2 часа вечером выделяю на проекты. Что самое странное, апи то работало, то не работало и уловить динамику появления ошибки у меня не получалось.

А решение, как обычно было рядом, проблема была в том, что я захлопывал крушку ноутбука :D Точнее так, сервисы я стараюсь сразу делать в родной среде, тобишь на линуксе, для этих делов, у меня есть virtualbox, в котором живут виртуалки с линуксом. Пока я работаю над одним сервисом, выключать виртуалки не приходится. Я их просто перетащил на другой рабочий стол и сижу себе спокойно по ssh, делаю tail -f на лог ошибок.

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


Про ценообразование при разработке сайтов.

Наткнулся на замечательный текст, от парня из OwlBox. Хочу сохранить сюда на память, что бы перечитывать когда в очередной раз мне предложат "помочь с сайтом" за кегу пива.

Каждый раз, когда я начинал трогать мышку менее чем за 1000$ я потом сильно жалел, не бывает "простеньких сайтов", аппетит приходит во время еды, требования плывут, и все в рот имели итеративный подход, если итерации сопровождаются соответствующими выплатами и этапами по договору. Это даже с точки зрения бухгактерии не выгодно. Это нижний порог. У хороших студий эта планка в 10 раз выше. На мой взгляд это правильная политика. При скудном бюджете есть миллион разных способов продвижения в интернете своих услух, не требующих сайта, работающего на имидж или выполняющего роль инструмента продаж.
Если обсуждается сумма ниже 1000$ — мы друг–друга просто не поймем, может быть кто–то другой поймет. От заказов нужно уметь оказываться.

Имидж — это декларация того, что мы можем потратить приличные бабки за хороший, годный, красивый и эффективный относительно целей заказчика сайт. Возможны комбинации. Но ключевой момент — потратить бабки и какие–то положительные свойства сайта. Я принципиально против того, что унитаз, покрытый позолотой эквивалентен золотому унитазу и вообще когда одно выдается за другое. Так как то, что король голый, как правило, все равно очевидно. Ну если вы не являетесь говносыночком пидораса из говноправительства, заказывающего сайт для говносколково.

Средний ценник среднего проекта под ключ у меня получается в районе $5000. Всякая верстка — это 1–15% от объема работ работы. Основной объем падает на тестирование и удовлетворение меняющихся требований. Пусть дизайн будет 1000$, программирование — 1000$ верстка и изготовление графического контента — еще $1000. На пальцах — это расклад при котором все участники процесса довольны.

С огромной вероятностью стоимость проекта относительно объема работ в итоге составит 5000–10000$ — косвенные расходы, непредвиденные работы, тестирование, изменений, детализация требований, дополнительные встречи с заказчиком, переговоры и т.д. Вот и получилось x2.

Если натягивается готовый шаблон на готовый движок, то все равно внезапно окажется что у нас не два уровня иерархии разделов, а все–таки 3, секретарша не справляется с wysywig редактором, гамма должна быть несколько светлее, внезапно образуется еще 200 единиц графического контента, шаблон выглядит как полное говно в IE6, которым пользуется заказчик из–за своей внутрикорпоративной политики и т.д.

Если вы не поняли — именно на это говно уйдет половина вашей работы. Если вам заказывают сайт по вашей оценке на 10k$, но бюджет заказчика позволяет всего лишь 7,5k$ а сам он видел что "что–то такое же" вообще делали за штуку и считает что за такие бабки получит священный грааль с элексиром вечной молодости, то это не клевый крупный заказ. Это плохая мерзкая жопа в которую вы гарантированно влезете. К тому же, с большой вероятностью, вы и объем работ оценили неправильно и он не на 10k$, а на 15k$ или больше.

Другой взгляд: если заказчик хочет хоть как–то заниматься продвижением, то либо сам сайт или его услуги должны быть просто замечательными, а это либо дорого либо сложно, соответственно, либо, если, это хоть сколько ни будь конкурентный рынок и область продвижения, стоимость продвижения будет составлять большое количество штук баксов. Очень странно, если конечная точка, куда приходит посетитель, будет стоит 100$

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


Picasa vs. Flickr

Опять я оказался в ситуации, когда являюсь не типичным пользователем. На этот раз проблема коснулась фотографий. Ситуация следующая: у меня есть оплаченный google storage на 20 или 25 гб, есть огромное колличество фотографий в пикасе, есть много новых фотографий которые я хочу залить в хранилища, знать что они в безопастности и иметь возмножность показывать их друзьям и родственникам, но у меня нету возможности.

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

Наверно тут стоит бросить камень в сторону Aperture, которым я пользуюсь как инструментом для обработки и каталогизации фотографий. Для меня всегда было странно, что подобные, крупные, программы или сервисы не делают все возможное для расширения. Да, безусловно, можно установить PicasaUploader, который позволит загружать выбранные фотографии в пикасу, но мне это не нравится. Я хочу, что-бы можно было нажать кнопочку "Sync this gallery" и далее она будет автоматически синхронизироваться с сервисом, а именно вносить изменения в фотографии если я сделал их у себя, обновлять/удалять определенные фото ну и остальные приятныем мелочи.

Для меня не понятно, почему поддержка flickr есть из коробки, а picasa нету.

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

К слову говоря, про Aperture, для меня остается загадкой, почему в 2012 году, они не научились делать некоторые фотографии скрытыми. Нельзя сделать как в пикасе, отметить несколько фотографий в альбоме как скрытые и их показ будет возможен только после ввода пароля.

Что делать в итоге - не решил. Ясно, что использовать пикасу, по определенным обстоятельствам, у меня не получится, но и пользоваться фликром желания тоже нету. Хотя, видимо это вопрос времени и если я не научусь делать свои плагины, то сдамся и начну переезд на фликр.


PHP - fastcgi_finish_request

А вы знаете про эту замечательную функцию?

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

Когда php работает в fastcgi режиме, например, в популярной связке nginx+php-fcgi, у вас появляется возможность сначала посчитать все данные которые необходимы что бы отдать пользователю страницу, а уже потом, когда страница отдана и nginx отдает ее клиенту, можно выполнить все остальные действия, например отправить письма или обновить кэш или запустить некие механизмы очистки.

Нужно отдельно упомянуть, что для правильной работы, fastcgi_finish_request должен запускать после session_write_close и ob_* функций.

Простой пример:

echo 'Hello word';

// В данной реализации, данные отдадутся в клиенту сразу,
// а если закомментировать вызов fastcgi_finish_request(),
// клиент будет ждать 10 секунд, до того, как получит ответ.
fastcgi_finish_request();

sleep(10);

9 million hits/day with 120 megs RAM

Оставлю у себя в закладках.

After checking this for about 9 months, I can tell you this almost always reads that number: 300 microseconds. This is about one third the time a camera flash illuminates. That’s, well, pretty quick. When I started, my software was taking about 0.25 seconds (250 000 microseconds) to produce the front page of my website. I needed to improve performance by over 800x.

Далее