Шутка дня

<!‐‐[if lte IE 7]> <style> * {font-family: "Comic Sans" !important;} </style> <![endif]‐‐>

css      

Thunderbird всё

thunderbird Многие люди радуются тому, что Mozilla закрывает поддержку Thunderbird с целью сфокусироваться на других задачах, а мне печально. Многие считают, что thunderbird это пережиток прошлого и при текущем витке интернета он остается не востребованным, ведь есть gmail и прочие облака. Я, честно говоря, даже чуть-чуть согласен, но объясните мне, как пользоваться Exchange'м в Linux?

При всей своей медлительности и неповоротливости, thunderbird оставался единственным вменяемым почтовым клиентом для *nix систем. Еvolution? Claws mail? Вы их видели? Это же верх уебищности. И веб-интерфейс у Exchange вменяем только под 9 IE, под остальными броузерами он выдает урезанную версию себя, которой пользоваться не возможно.

Возможно это все не проблема, для людей которые получают 10 писем в неделю, но я получаю примерно 10 писем в час и мне нужно уметь ими эффективно манипулировать.

Что делать? Я в печали.


mail, thunderbird, работа      

Почему жилье дорожает

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

Я Вам сейчас очень просто объясню, почему дома подорожали к зарплате - бензин тут ни при чем. Допустим, мы - я, Вы и Хроноскопист летели на самолете через Тихий океан. В пути мы втроем накушались абсента, надебоширили, отломали дверь от туалета, и нас за это выкинули в море через аварийный выход. По счастью, рядом с местом нашего падения обнаружился маленький безымянный полинезийский остров. Выбравшись на берег, мы посовещались, и решили считать его новым государством под названием Соединенные Штаты Абсента (США).

Когда нас выкидывали из самолета, то багажа нам, естественно, не выдали. Поэтому, всех материальных и нематериальных активов у нас - только туалетная дверь, которую Вы таки прихватили с собой. И вообще, несмотря на абсент, Вы у нас оказались самым запасливым - в бумажнике у Вас, совершенно случайно, обнаружилась банкнота в $100. Таким образом, в наших США имеются нефинансовые активы - дверь, и финансовые активы, они же денежная масса - $100. Это все наши сбережения. Поскольку у нас больше вообще ничего нет, то можно сказать и так - у нас есть один материальный актив - дверь, обеспеченный денежной массой в $100. Т. е. наша дверь стоит $100.

Немного протрезвев, мы решаем, что надо как-то обустраиваться. Самый быстрый из нас оказался Хроноскопист. Он тут же объявил, что создает банк и готов взять в рост имеющиеся у населения денежные сбережения под 3% годовых - ну не сидится человеку без дела. Вы отдаете ему $100, и он их записывает в блокнот в статью "Пассивы -\ Дипазиты". Но я тоже не лаптем щи хлебал - зря я что ли столько времени занимаюсь расследованием экономического мухлежа - я знаю как изъять у Вас и дверь и $100. Я предлагаю Вам взять Ваши $100 в рост под 5% годовых. Вырываю листик из своего блокнота и пишу на нем - "Аблегиция на $100 под 5% годовых". Вы чувствуете, что Вам поперло. Забираете деньги у расстроенного Хроноскописта с дипазита и отдаете их мне в обмен на мою аблегацию.

Я беру Ваши $100 и кладу их на дипозит в банк обратно обрадованного Хроноскописта.
По хорошему, на этом можно было бы и успокоиться и пойти всем заняться делом - пальму потрясти или за моллюсками понырять, снискать себе хлеб насущный, так сказать. Но Вы ж знаете - я неуемный финансовый гений, такие пустяки как кокосы и устрицы меня не интересуют. Помыкавшись по нашему острову - 50 шагов от южного побережья до северного, и 30 с запада на восток, я придумываю гениальную комбинацию. Я подхожу к Вам и предлагаю на пустом месте заработать еще 1% годовых. Взять в банке Хроноскописта кредит под 4%, и купить у меня еще одну аблигацию под 5%. Вторую аблегацию на $100 я тут же выписываю на блокнотном листике, и машу ею у Вас перед носом. Недолго думая, Вы бежите в банк и берете кредит $100 под залог моей первой аблегации на $100. Они там есть - я их туда положил на дипазит. Вы отдаете мне заемные $100 и прячете вторую аблегацию к себе в бумажник - теперь у Вас есть моих аблегаций на $200. А $100 я кладу в банк - теперь у меня там $200 на дипазите. Хроноскопист аж подпрыгивает от радости - кредитный бизнес попер.

Думаете я на этом остановлюсь? Ага, сейчас - я уже выписал Вам третью аблегацию. Бегом в банк за кредитом под залог второй аблегации. Ближе к вечеру, набегавшись по острову с этой сотней баксов и изодрав все листочки из блокнота на аблегации, мы имеем следующую картину. У Вас на $5000 моих аблегаций, а у меня на $5000 дипазитов в банке. Теперь, я чувствую, что пришло время прибрать Вашу дверь к рукам. Я предлагаю купить ее у Вас за $100. Но Вы вредничаете - дверь-то всего одна, и заламываете цену в $1000. Ну, $1000 так $1000 - в конце концов у меня на депозите лежит целых $5000. Я на последнем блокнотном листочке направляю платежное поручение Хроноскописту, перевести $1000 с моего дипазита на Ваш, и забираю Вашу дверь.

Если нашу бухгалтерию отдать американскому экономисту с гарвардским дипломом, он сообщит нам, что наши США располагают $1000 материальных активов в виде двери, и $10000 финансовых активов в виде аблегаций и дипазитов. Т. е. что стоимость нашего совокупного имущества увеличилась за день в 110 раз.

Менее тонкий и образованный человек сказал бы, что мы - три дебила, у нас как была одна дверь и $100, так и осталось, и что только конченные дебилы могли целый день рвать листочки из блокнота, вместо того, чтобы нарвать кокосов. Кто из них прав - решайте сами. Но механизм относительного роста цен на дома именно такой, что в США, что в Японии, что в России.


деньги, жизнь      

Percona Server Configuration Wizard

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

percona

Проходим небольшой тест, отвечая на вопросы и на выходе имеем подобный конфиг:

# Generated by Percona Configuration Wizard (http://tools.percona.com/) version REL5-20120208
# Configuration name zlo generated for gmail@rpsl.info at 2012-07-05 10:31:23

[mysql]

# CLIENT #
port                           = 3306
socket                         = /srv/mysql/mysql/mysql.sock

[mysqld]

# GENERAL #
user                           = mysql
default_storage_engine         = InnoDB
socket                         = /srv/mysql/mysql/mysql.sock
pid_file                       = /srv/mysql/mysql/mysql.pid

# MyISAM #
key_buffer_size                = 32M
myisam_recover                 = FORCE,BACKUP

# SAFETY #
max_allowed_packet             = 16M
max_connect_errors             = 1000000
skip_name_resolve
sysdate_is_now                 = 1
innodb                         = FORCE

# DATA STORAGE #
datadir                        = /srv/mysql/mysql/

# CACHES AND LIMITS #
tmp_table_size                 = 32M
max_heap_table_size            = 32M
query_cache_type               = 0
query_cache_size               = 0
max_connections                = 500
thread_cache_size              = 50
open_files_limit               = 65535
table_definition_cache         = 1024
table_open_cache               = 256

# INNODB #
innodb_flush_method            = O_DIRECT
innodb_log_files_in_group      = 2
innodb_log_file_size           = 128M
innodb_flush_log_at_trx_commit = 1
innodb_file_per_table          = 1
innodb_buffer_pool_size        = 1456M

# LOGGING #
log_error                      = /srv/mysql/mysql/mysql-error.log
log_queries_not_using_indexes  = 1
slow_query_log                 = 1
slow_query_log_file            = /srv/mysql/mysql/mysql-slow.log

Ну и в качестве бонуса, рекомендую почитать доклад "Optimizing MySQL Configuration" от Percona


mysql, percona      

Nginx allow POST static files

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

Мое решение лучше тем, что оно не требует поднятия второго сервера на отдельном порту и вообще эстетически красивое.

Кратко о проблеме:

Все знают о том что в Facebook'e есть iframe страницы, но не все знают что Facebook эти страницы запрашивает через POST, а не через GET, как делают все остальные. Поэтому все fb:iframe приложения запрашивая у Nginx'а страницы в ответ будут получать ошибку:

405 "Method Not Allowed"

Вариант который предлагает dotZero выглядит примерно вот так ( это я для истории и поисковых запросов оставлю ):

upstream fb_static {
    server localhost:8001;
}

server {
    listen       443;
    server_name  _;

    #allow_static_post on;

    error_page 405 =200 @405;

    location @405 {
        proxy_method GET;
        proxy_pass http://fb_static;
    }
}

server {
    listen 8001;
    server_name _;

    location / {
        root "/var/www/fb";
    }
}

Вариант конечно хороший и самое главное рабочий, но чисто эстетически он убогий. Давайте попробуем так:

server {
    listen  80;
    server_name _;

    # Тут мы описываем поведение
    # для нашей кастомной ошибки
    error_page 405 = $uri;

    # Дефолтный location
    location / {
        access_log off;
        root    /srv/path
        try_files $uri $uri/index.html /index.php$is_args$args;
    }
}

Что тут происходит? Мы складываем весь статический контент который будет запрашивать facebook в отдельную директорию, просто, для красоты. Определяем location для этой директории, который будет всегда возвращать код ошибки, например, 599. И определяем поведение для обработки этой ошибки, как попытку отдать данные по этому урлу.

Вот и все, работает. Читайте мануалы.

UPD: вернул конфиг до состояние обработки напрямую 405 error_page, т.к. поведение описанное до этого, не совсем соответствовало реальности. Таки образом, после запроса файла через POST, будет выдана 405 ошибка, которая обработается в error_page 405 = \$uri и будет отправлена в location /. То есть либо файл найдется и будет отдан, либо управление будет передано в index.php.


facebook, nginx      

PHP: detect UTF-8

Пару недель назад, мне кто-то доказывал, что mb_detect_encoding, работает в разы быстрее своих надуманных конкурентов. Задача простая, проверить входящую строку на принадлежность к UTF-8. Логика простая, либо UTF-8, либо нет. В повседневной жизни, обычно не приходится выбирать из зоопарка кодировок и, чаще всего, строка либо в utf8, либо в cp1251.

Сделал простой синтетический тест. Прогнал определение через функцию 10000 раз. Посмотрел кто быстрее.

Вариант 1, который мне нравится:

$s = microtime(true);

for( $i=0; $i<10000; $i++ )
{
    $string = 'sdf;gklaj;skdjf;sdkfls;dfjk';

    if( preg_match('//u', $string ) )
    {

    }
}

$e = microtime(true);

echo "\n\n" . $e-$s;

Средний результат выполнения скрипта на моей машине ~0.020 сек. Сравнивал я его с более правильным решением, которое выглядит так:

$s = microtime(true);

for( $i=0; $i<10000; $i++ )
{
    $string = 'sdf;gklaj;skdjf;sdkfls;dfjk';

    mb_detect_encoding( $string, array('UTF-8'), true );
}

$e = microtime(true);

echo "\n\n" . $e-$s;

Средний результат выполнения скрипта на моей машине ~0.050 сек. После этих тестов, решил прогнать на больших объемах данных, сгенерировал текст размером 10к байт и пропустил через ф-ции. Для preg_match время выполнения составило ~0.120 сек, для mb_detect_encoding ~0.7 сек. Из этих изысканий можно сделать вывод, что определение через preg_match работает в разы быстрее чем стандартные механизмы, но, вероятно, проигрывает в количестве доступых фич. На самом деле, есть еще три миллиона разных способов решить эту задачу, расскажите чем пользуетесь вы?


php, utf      

Про webmoney

В прошлом посте я писал про молоток, вспомнил, что несколько месяцев назад со мной приключилась беда. Каким то неведомы макаром, мои ключи к киперу стали не действительными. Примерно в это же время, на одном несуществующем сайте, появился чувак который занимает руководящую должность в этой конторе. Он попросил всех рассказать свои success story про пользование системой. Ну вот я и рассказал. Сюда перенесу на память.

webmoney

Есть у меня виртуалка, живет уже много лет, в ней крутится только Win XP и кипер класик. Апдейты там еще какие–то ставятся хз. Кроме кипера и Google Chrome в ней вообще ничего нету используется раз в месяц для вывода денег из sape и транзита этих денег на оплату мобильника, инета, серверов.

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

Через пару дней собрался силами и прошел этот квест снова, далее неделя ожидания и куча ебанутых писем на почту о статусе моей заявки "Костя из саппорта проверил ваши данные", "Дима из саппорта подтвердил ваши данные", "Ваша заявка передана из отдела саппорта в отдел заявок" — Нахуй мне это знать??? Мне важно что заявка получена вами и что на нее пришел ответ. Спустя неделю получил новый файл ключей, залогинился, снова, блядь, активируйте вашу систему, ссылка отправленна на почту.

Потом я уже почитал этот пост, решил сделать себе из кипер классик — кипер мини, енум, клиент для мака, полтора часа попыток понять что это и нахуй оно вообще нужно, 2000 пройденых каптч, 50 полученых смс и ачивка "Вебмани в МакОС" получена.

Спасибо. Охуеть. Сдохните.


webmoney      

Молоток.ру и забота о пользователях

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

У вас кстати есть карточка от много.ру? Я ее случайно лет 10 назад завел. Прошло лет 9 как я ее потерял, но письма они продолжают слать, у них видимо не хватает мозгов додумать, что аккаунты которые не подавали активности последние 10 лет можно считать не валидными.

Так вот, возвращаясь к молотку. Как меня бесит, что нельзя отписаться от рассылки в один клик. Чтобы отписаться от рассылки, нужно пройти на их сайт, войти в свой аккаунт и там настроить систему уведомлений.

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

trololo

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


mail, spam      

Nginx detect mobile browser

Регулярка для Nginx

set $mobile_rewrite do_not_perform;

if ($http_user_agent ~* "android.+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge|maemo|midp|mmp|netfront|opera m(ob|in)i|palm(os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino") {
  set $mobile_rewrite perform;
}

if ($http_user_agent ~* "^(1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-||_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac(|\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-)") {
  set $mobile_rewrite perform;
}

if ($mobile_rewrite = perform) {
  rewrite ^ http://m.site.com/ redirect;
  break;
}

Ну и собственно вот тут собранные подобные рецепты для различных языков и сервисов.


mobile, ngixn      

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 страниц.

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


centr, mysql, nginx