<!‐‐[if lte IE 7]> <style> * {font-family: "Comic Sans" !important;} </style> <![endif]‐‐>
Вообще, у меня сегодня были планы рассказать вам про мои ощущения от 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, так и осталось, и что только конченные дебилы могли целый день рвать листочки из блокнота, вместо того, чтобы нарвать кокосов. Кто из них прав - решайте сами. Но механизм относительного роста цен на дома именно такой, что в США, что в Японии, что в России.
Возможность генерировать удобный конфиг для mysql прямо на сайте перконы для меня стало открытием. Есть возможность указать различные характеристики железа и роль данного сервера, а сайт постарается подобрать оптимальные настройки.
Проходим небольшой тест, отвечая на вопросы и на выходе имеем подобный конфиг:
# 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
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
.
Пару недель назад, мне кто-то доказывал, что 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 работает в разы быстрее чем стандартные механизмы, но, вероятно, проигрывает в количестве доступых фич.
На самом деле, есть еще три миллиона разных способов решить эту задачу, расскажите чем пользуетесь вы?