Высокие нагрузки, оптимизация и всякое такое

И снова здравствуйте!

Как оказалось, День Знаний на самом деле сегодня, поэтому продолжаем разговор.

Отложим практику и займёмся теорией и немного философией.

Поговорим про оптимизацию приложений. А так как преждевременная оптимизация — смертный грех, то про оптимизацию нагруженных приложений.
Не будем лезть в подробности, а просто попробуем разобраться в каких местах вообще следует оптимизировать.

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

Остальной текст под катом

Пользователи на сайте: Memcached vs MySQL-JOIN

Здравствуйте, дорогие друзья, с вами снова Блог ГО.

Сегодня, в День Знаний, разберём одну тему. Тема, не так, чтобы для старших классов, но уже и не для дошкольников.

Рассмотрим один из вариантов хранения данных о пользователях в мемкэше.

Постановка задачи

Есть, допустим, сайт, а на нём есть зарегистрированные пользователи. Их данные хранятся, обычно, в таблице наподобие следующей:

CREATE TABLE `users` (
	`user_id`  INT UNSIGNED NOT NULL AUTO_INCREMENT,
	`username` VARCHAR(20)  NOT NULL,              -- Имя
	`surname`  VARCHAR(20)  NOT NULL,              -- Фамилия
	`nickname` VARCHAR(50)  NULL DEFAULT NULL,     -- Ник
	`avatar`   BOOL         NOT NULL DEFAULT "0",  -- Наличие аватара
	`status`   ENUM("active", "banned", "deleted") DEFAULT "active", -- Активный, забаненый, удалённый
	-- ...
	PRIMARY KEY (`user_id`)
	-- ...
);

Остальной текст под катом

goDB 1.1.3

После года разгильдяйничества, решил снова заняться своей библиотечкой для работы с MySQL.

Изменения в версии 1.1.3 незначительны, но, надеюсь, что вскоре будет что-нибудь поинтереснее.

Остальной текст под катом

Сериализация с Igbinary

Дошли, наконец, руки поставить и протестировать PHP-расширение Igbinary, о котором сегодня и поведую.

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

$A = array(1, 2, 'three', true);
$s = serialize($A);
 
var_dump($s); // 'a:4:{i:0;i:1;i:1;i:2;i:2;s:5:"three";i:3;b:1;}'

Для подобных действий используются функции serialize() и unserialize. Кроме того сериализация происходит неявно для данных сессий, значений в мемкэше и др.

Основной недостаток стандартной сериализации: формат строки — слишком многословный. Именно эту проблему решает Igbinary, сохраняя данные в компактной двоичной последовательности.

Остальной текст под катом

Плохая цобако

Писец, сколько людей упёртых не там, где надо. Нахватались поначалу «правильных советов от великих гуру» и теперь остальным мозг выносят. «Никогда не используйте eval», «никогда не используйте @ в PHP»…

Действительно ли никогда нельзя использовать собаку (@) в пыхе? Давайте просто головой подумаем.

Итак, как можно бороться с ошибками в программном коде? Есть два основных способа:

  1. Путём их игнорирования.
  2. Путём их корректной обработки.

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

Нам нужна корретная обработка. Однако, ошибки бывают разные и способы их корректной обработки тоже разные.

Первый тип ошибок: ошибки в программе. Синтаксическая ошибка, в запросе опечатались, лень было проверить существование запрашиваемого ключа в массиве и т.п. Аналог проверяемых исключений (RuntimeException). Корректная обработка подобных ошибок может быть только одна — исправление программного кода на этапе разработки. И для этого нам нужно чётко отлавливать их появление и ни в коем случае не подавлять сообщения о них. Здесь собака действительно вредна.

Второй тип — непроверяемые. Сервер базы данных отвалился, сокет не открывается. На этапе разработки мы не можем устранить возможность подобных происшествий. Единственное, что можем, это обрабатывать эти ситуации. Пример:

$lid = mysql_connect($host, $user, $password);
if (!$lid) {
    throw new Exception('MySQL fail');
}

Мы не спрятали голову в песок. Мы корректно обработали возможную ошибку. Но вот незадача — несмотря на это, mysql_connect() всё равно выкинет совершенно уже ненужный нам Warning.

К чёрту Warning!

$lid = @mysql_connect($host, $user, $password);
if (!$lid) {
    throw new Exception('MySQL fail');
}

Вывод: слушайте умных дядей, но и своей головой думайте.

goPaginator: отрисовка пагинатора

Начинаю раздел goLibs с выкладыванием простеньких вспомогательных классиков. Первым на очереди идёт goPaginator. Можно просмотреть исходный код или скачать ZIP.

Основная задача библиотеки — отрисовка пагинатора и помощь в выборки данных для текущей страницы. Простейший пример (более развёрнутый пример можно пощупать здесь):

/* Общее количество элементов в списке, разбиваемым на страницы */
$countElements = query('SELECT COUNT(*) FROM `table`');
if ($countElements == 0) {
	echo 'Список пуст';
	return;
}
 
$pager = new goPaginator($countElements); // Создаём объект пагинатора
 
echo $pager; // Выводим пагинатор сверху
 
/* Выборка и вывод элементов для текущей страницы */
$sql = 'SELECT * FROM `table` ORDER BY `id` ASC LIMIT '.$pager->getSqlLimits();
$elements = query($sql);
foreach ($elements as $element) { /* Выводим элементы */ }
 
echo $pager; // Пагинатор снизу

Остальной текст под катом

Автолоад без __autoload

Функция __autoload(), как все знают, очень полезна. Её появление в PHP5 значительно упростило всем жизнь. А появление spl_autoload_register() упростило ещё больше.

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

Остальной текст под катом

PHP Extension: Date/Time

Что-то я совсем разленился и перестал быть в курсе нововведений в PHP. Дабы исправить это, я решил перечитать документацию по всем расширениям языка. А заодно и вывалить краткие отчёты по этому на головы моих неподготовленных читателей. Может быть, для других лентяев что-нибудь окажется полезным.

Сегодня рассмотрим новые (относительно) средства для работы со временем, появившиеся в PHP 5.2 (с 5.1 в ранге экспериментальных). Для меня, в большинстве случаев, работа с ними, заканчивается на вызове в начале программы date_default_timezone_set(), иначе при E_STRICT выскакивает предупреждение.

Однако, новые средства довольно забавны и, вполне, могут сделать жизнь проще и веселее.

Остальной текст под катом

Немного багов

Детские ошибки, которые в последнее время отъели у меня немало времени и нервов. Разрабатывая сложные вещи не забывайте и о подобной чепухе. (Все примеры сведены к бессмысленному минимально иллюстрирующему коду).

OR

В PHP, как самом умном, результатом операторов && и || является TRUE/FALSE. Казалось бы, логично, что результатом логического оператора является логическое значение. Однако, другие языки развратили меня тем, что возвращают в этом случае значение одного из аргументом.

В итоге строка $x || $y || $z вместо целочисленного значения одной из переменных, вернула предательский TRUE. После нелёгких поисков пришлось одну строку заменять на кучу ветвлений.

Остальной текст под катом

Перехват отправляемого email

Начинаем рубрику «для самых маленьких», с решением простеньких проблем.

Есть такая функция в PHP — mail(), и отправляет она, как все знают, электронную почту. Чуть меньше народу знает, что на самом деле отправляет не она, а mail-сервер, которому она просто передаёт письмо.

Ситуация с настоящим mail-сервером при тестировании сайта на локалке (под Windows) несколько неудобна по двум причинам. Во-первых, достаточно геморойно его установить. Во-вторых, при тестировании обычно не нужно действительно рассылать письма по настоящим адресам. Лучше всего в локальной версии все отправляемые письма складывать в отдельную папочку. Сразу видно сколько писем было отправлено, кому и что у них внутри.

Остальной текст под катом

По страницам: 1234