ejabberd

ejabberd — самый популярный сервер для сети обмена мгновенными сообщениями Jabber/XMPP. Его успех сравним с успехом Apache — обладая целым рядом проблем, этот сервер всё-таки стал стандартом де-факто за счёт отсутствия альтернатив на протяжении долгого времени. В этой статье я рассказываю некоторые свои идеи, которые не претендуют на достоверность и не являются чем-либо подкреплёнными, однако, могут послужить пищей для размышления для всех желающих поднять свой Jabber-сервер на базе ejabberd.

О кластеризации

Кластеризация ejabberd — хороший способ повышения отказоустойчивости. Однако, далеко не всегда она способна принести желаемый результат. Рассмотрим такую ситуацию. К примеру, к ноде ejabberd, работающей на VPS srv1 и использующей базу данных MySQL/PostgreSQL на srv1, добавляется нода на srv2. Она обязана использовать тот же самый сервер баз данных, то есть srv1. Таким образом, сервер баз данных становится единой точкой отказа, и отключение srv1 приведёт к неработоспособности ejabberd на srv2 по причине невозможности доступа к данным. Это означает необходимость кластеризации СУБД, что может оказаться нетривиальной задачей. Однако, если srv1 является не VPS, а выделенным сервером, добавление второй ноды может быть полезным даже в случае использования общей СУБД на srv1 — по той простой причине, что ejabberd менее стабильно, чем СУБД, и вторая нода может послужить страховкой на случай отказа первой ноды при сохранении работоспособности сервера srv1.

Использование TLS

TODO

Зачистка

Сервер растёт — растёт и база. Но, к сожалению, она наполняется не только полезным содержимым. Следующая серия запросов позволяет вычистить из базы лишние данные (при использовании MySQL):

DELETE FROM last WHERE username NOT IN (SELECT username FROM users);
DELETE FROM users WHERE username IN (SELECT username FROM last WHERE seconds < <span style="color: #F00;">TIMESTAMP</span>);
DELETE FROM rosterusers WHERE username NOT IN (SELECT username FROM users);
DELETE FROM rostergroups WHERE username NOT IN (SELECT username FROM users);
DELETE FROM private_storage WHERE username NOT IN (SELECT username FROM users);
DELETE FROM privacy_list_data WHERE id IN (SELECT id FROM privacy_list WHERE username NOT IN (SELECT username FROM users));
DELETE FROM privacy_list WHERE username NOT IN (SELECT username FROM users);
DELETE FROM privacy_default_list WHERE username NOT IN (SELECT username FROM users);
DELETE FROM last WHERE username NOT IN (SELECT username FROM users);
DELETE FROM spool WHERE username NOT IN (SELECT username FROM users);

Обратите внимание на значение TIMESTAMP, выделенное цветом. На её место вам нужно поместить UNIX timestamp. Скрипт удаляет пользователей, не подключавшихся позже этого timestamp, и все их данные. Внимание: скрипт громоздкий и может работать долго, его лучше запускать в консоли, нежели в phpMyAdmin!

На высокозагруженных серверах в таблице spool иногда может скапливаться значительный объём оффлайн-сообщений — миллионы и десятки миллионов рядов. В частности, при DoS-атаках большая часть таких сообщений может быть бесполезной. В таких случаях можно очистить таблицу, но если принимать столь крайнюю меру не хочется, можно использовать вот такой запрос для удаления всех оффлайн-сообщений старше определённой даты.

DELETE FROM spool WHERE created_at < '2011-09-07 00:00:01';

Обратите внимание: при описанных выше условиях этот запрос феерически громоздок (отчасти из-за отсутствия индекса на столбце created_at) и может выполняться от нескольких минут до нескольких часов. Кстати, последнюю задачу можно решить и используя ejabberdctl.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>