Доброго времени суток!
Небольшое предисловие: не так давно увидели свет 13-я, а за ней в этом году и 14-я версии ejabberd. Process One решили сменить схему версионирования в силу ряда причин и версии 2.x сейчас уже считаются устаревшими. Новый ejabberd поделился на две ветки — ejabberd Community Server и ejabberd Business Edition и начал довольно активно развиваться.
В нашем случае, в качестве системы была выбрана FreeBSD, так как требуется поддерживать довольно большое количество соединений на ноду (~100k).
На установке системы смысла останавливаться не вижу, поэтому под катом сразу перейдем к настройке.
Часть своих данных ejabberd будет хранить в mysql, поэтому в системе должны быть установлены библиотеки odbc. Так же мы используем скрипт внешней авторизации на php, поэтому нужен и php.
Этап 1:
Ставим пререквизиты (git, fop, libyaml, wget, unixODBC, expat, wx30-gtk2, php5, etc):
Качаем последнюю версию эрланга (на момент написания статьи 17.2.2):
Собираем, ставим его:
Далее качаем ejabberd и ejabberd-contrib:
Создаем пользователя ejabberd, в качестве домашней директории указываем /var/lib/ejabberd.
Собираем и ставим ejabberd:
При сборке erlang и ejabberd могут возникнуть различного рода нюансы, аля потребуется создать ряд симлинков из /usr/local/lib | include в /usr/lib | include или «поиграться» с LDFLAGS / CPPFLAGS.
Собираем mod_admin_extra, для расширения списка доступных команд в ejabberdctl и через xmlrpc:
Этап 2:
Основной конфигурационный файл ejabberd.yml изобилует примерами и комментариями разработчиков, поэтому настроить его не сложно. В yaml-конфигурационных файлах важна табуляция, редактор хабра у меня её съел, поэтому будьте внимательны! Остановлюсь лишь на некоторых параметрах:
В секции ejabberd_c2s:
Для внешней авторизации:
Для подключения к mysql:
Прописываем «админа»:
Переключаем часть модули на работу с mysql:
Подключаем mod_admin_extra:
Правим ejabberdctl.cfg (параметры индивидуальны, но я привожу те, что прописаны у нас):
Идем на mysql-сервер, создаем там базу и заливаем в неё дамп из mysql.sql из папки sql исходников ejabberd.
Запускаем!
Создаем пользователя admin:
Этап 3:
Для создания кластера берем еще один сервер и проделываем процедуры, описанные выше.
Чтобы репликация между нодами работала корректно (да и вообще чтобы собрать кластер) нужно, чтобы ноды могли соединяться друг с другом по порту 4369 и теми портами, что вы указали в FIREWALL_WINDOW.
Копируем файл /var/lib/ejabberd/.erlang_cookie c первой ноды на вторую и если проблем с соединениями между нодами нет, то собираем кластер:
Вызываем mnesia:info().
Если все хорошо, то в списке running db nodes у вас будут обе ноды.
Меняем схему сохранения таблиц, выходим и запускаем:
Этап 4:
Немного о параметрах системы:
Если все прошло нормально, то зайдя в админку youserver.com:5280/admin/nodes/ в Running Nodes будут обе ноды.
mod_admin_extra значительно расширяет список команд, которые можно передать через ejabberdctl. Если вы оставили активным модуль ejabberd_xmlrpc (который стал встроен в ejabberd с 13-й версии), то команды jabber-серверу можно передавать и через XmlRPC. Мы, к примеру, управляем ростером, группами, vcard'ами и прочим через специальные worker'ы, написанные на php. Но, по сути, подключаться к xmlrpc можно из чего угодно.
Что касается потребляемых ресурсов, то для 100 тысяч подключенных пользователей требуется где-то под 25-30 Gb памяти (это при хранении большинства данных в mysql, т.е. чисто на обслуживание подключенных клиентов). Если хранить данные в mnesia, то цифра легко может дойти до 100 Gb и больше, но тут все зависит от количества пользователей и данных в базе.
К сожалению, в сети очень мало примеров успешных инсталляций ejabberd, которые работают с десятками тысяч подключенных пользователей. Лично я натыкался лишь на «слухи» о том, что значительно патченный ejabberd — основа сервисов WhatsApp. Да и, сам по себе, erlang — отдельная песня, к которой бывает не так просто найти подход :) Mailing-листы ejabberd тоже в полумертвом состоянии, и проконсультироваться с кем-то о возможных проблемах на high-load проблемно, поэтому многое приходится изучать с горьким опытом. Радует, что ejabberd сейчас довольно активно развивается (по сравнению с периодом до второй половины 2013 года), появляется новый функционал. В этом году появились несколько major-контрибуторов из сообщества, которые регулярно правят баги, оставшиеся с 2.х версий или вновь приобретенные.
Рад буду найти «сообщников», которые используют ejabberd в своих сервисах — быть может сможем продуктивно поделиться опытом друг с другом!
P.S. Буду благодарен за указание недочетов (желательно в личку) и рад любым комментариям. Спасибо!
Небольшое предисловие: не так давно увидели свет 13-я, а за ней в этом году и 14-я версии ejabberd. Process One решили сменить схему версионирования в силу ряда причин и версии 2.x сейчас уже считаются устаревшими. Новый ejabberd поделился на две ветки — ejabberd Community Server и ejabberd Business Edition и начал довольно активно развиваться.
В нашем случае, в качестве системы была выбрана FreeBSD, так как требуется поддерживать довольно большое количество соединений на ноду (~100k).
На установке системы смысла останавливаться не вижу, поэтому под катом сразу перейдем к настройке.
Часть своих данных ejabberd будет хранить в mysql, поэтому в системе должны быть установлены библиотеки odbc. Так же мы используем скрипт внешней авторизации на php, поэтому нужен и php.
Этап 1:
Ставим пререквизиты (git, fop, libyaml, wget, unixODBC, expat, wx30-gtk2, php5, etc):
pkg install git fop libyaml wget unixODBC-2.3.2 expat wx30-gtk2 php5 ... (+ все что вам нужно)cd /usr/ports/java/openjdk7/make install cleanКачаем последнюю версию эрланга (на момент написания статьи 17.2.2):
mkdir /usr/local/src && cd /usr/local/srcgit clone git://github.com/erlang/otp.gitСобираем, ставим его:
cd /usr/local/src/otpautoconf -f./configure --prefix=/usr/local --enable-kernel-poll --with-ssl --enable-threads --with-odbc --enable-smp-support gmakegmake installДалее качаем ejabberd и ejabberd-contrib:
cd /usr/local/srcgit clone git://github.com/processone/ejabberd.gitgit clone git://github.com/gamenet/ejabberd-contrib.gitСоздаем пользователя ejabberd, в качестве домашней директории указываем /var/lib/ejabberd.
Собираем и ставим ejabberd:
cd /usr/local/src/ejabberdautoconf -f./configure --enable-mysql=yes --enable-odbc=yes --enable-lager=yes --prefix=/usr/local --localstatedir=/var --enable-user=ejabberdgmake && gmake installПри сборке erlang и ejabberd могут возникнуть различного рода нюансы, аля потребуется создать ряд симлинков из /usr/local/lib | include в /usr/lib | include или «поиграться» с LDFLAGS / CPPFLAGS.
Собираем mod_admin_extra, для расширения списка доступных команд в ejabberdctl и через xmlrpc:
cd /usr/local/src/ejabberd-contrib/mod_admin_extra./build.shcp ./ebin/mod_admin_extra.beam /usr/local/lib/ejabberd/ebin/Этап 2:
Основной конфигурационный файл ejabberd.yml изобилует примерами и комментариями разработчиков, поэтому настроить его не сложно. В yaml-конфигурационных файлах важна табуляция, редактор хабра у меня её съел, поэтому будьте внимательны! Остановлюсь лишь на некоторых параметрах:
hosts: - "youserver.com"В секции ejabberd_c2s:
backlog: 1024 Для внешней авторизации:
auth_method: externalextauth_program: "/usr/local/bin/<ваш_скрипт>.php"extauth_instances: 12extauth_cache: 72000Для подключения к mysql:
odbc_type: mysqlodbc_server: "mysql_server_ip"odbc_database: "dbname"odbc_username: "username"odbc_password: "password"odbc_pool_size: 16odbc_keepalive_interval: 600Прописываем «админа»:
admin: user: - "admin": "yourserver.com"Переключаем часть модули на работу с mysql:
mod_last: db_type: odbc mod_muc: db_type: odbc mod_offline: db_type: odbc mod_privacy: db_type: odbc mod_private: db_type: odbc mod_roster: db_type: odbc mod_shared_roster: db_type: odbc mod_vcard: db_type: odbcПодключаем mod_admin_extra:
mod_admin_extra: {}Правим ejabberdctl.cfg (параметры индивидуальны, но я привожу те, что прописаны у нас):
ERL_MAX_PORTS=524288FIREWALL_WINDOW=4200-4210ERL_PROCESSES=5000000ERL_MAX_ETS_TABLES=262144ERLANG_NODE=ejabberd@node1Идем на mysql-сервер, создаем там базу и заливаем в неё дамп из mysql.sql из папки sql исходников ejabberd.
Запускаем!
su - ejabberdejabberdctl startСоздаем пользователя admin:
ejabberdctl register admin yourserver.com passwordЭтап 3:
Для создания кластера берем еще один сервер и проделываем процедуры, описанные выше.
Чтобы репликация между нодами работала корректно (да и вообще чтобы собрать кластер) нужно, чтобы ноды могли соединяться друг с другом по порту 4369 и теми портами, что вы указали в FIREWALL_WINDOW.
Копируем файл /var/lib/ejabberd/.erlang_cookie c первой ноды на вторую и если проблем с соединениями между нодами нет, то собираем кластер:
su - ejabberderl -sname ejabberd@node2 -mnesia dir '"/var/lib/ejabberd/"' -mnesia extra_db_nodes "['ejabberd@node1']" -s mnesiaВызываем mnesia:info().
Если все хорошо, то в списке running db nodes у вас будут обе ноды.
Меняем схему сохранения таблиц, выходим и запускаем:
mnesia:change_table_copy_type(schema, node(), disc_copies).q().ejabberdctl startЭтап 4:
Немного о параметрах системы:
loader.conf
kern.ipc.maxsockets=2400000.
kern.ipc.nmbclusters=0
net.inet.tcp.reass.maxsegments=2048
vm.pmap.shpgperproc=400
hw.em.rxd=4096
hw.em.txd=4096
hw.em.rx_int_delay=100
hw.em.tx_int_delay=100
hw.em.rx_abs_int_delay=1000
hw.em.tx_abs_int_delay=1000
dev.em.rx_processing_limit=-1
net.inet.tcp.hostcache.hashsize=4096
net.inet.tcp.hostcache.bucketlimit=100
net.inet.tcp.hostcache.cachelimit=65536
net.inet.tcp.syncache.hashsize=4096
net.inet.tcp.syncache.bucketlimit=120
net.inet.tcp.syncache.cachelimit=131072
net.inet.tcp.tcbhashsize=524288
net.isr.defaultqlimit=4096
net.isr.bindthreads=1
net.isr.maxthreads=4
net.link.ifqmaxlen=1024
sysctl.conf
kern.ipc.shm_use_phys=1
kern.ipc.somaxconn=8192
kern.maxfiles=3000000
kern.maxfilesperproc=2700000
kern.maxvnodes=256000
kern.random.sys.harvest.ethernet=0
kern.random.sys.harvest.interrupt=0
kern.sync_on_panic=1
net.inet.icmp.bmcastecho=0
net.inet.icmp.drop_redirect=1
net.inet.icmp.maskrepl=0
net.inet.ip.intr_queue_maxlen=256
net.inet.ip.maxfragpackets=1024
net.inet.ip.portrange.first=1024
net.inet.ip.portrange.last=65535
net.inet.ip.portrange.randomized=0
net.inet.ip.redirect=0
net.inet.ip.sourceroute=0
net.inet.ip.accept_sourceroute=0
net.inet.tcp.blackhole=2
net.inet.tcp.drop_synfin=1
net.inet.tcp.fast_finwait2_recycle=1
net.inet.tcp.finwait2_timeout=3000
net.inet.tcp.hostcache.expire=1200
net.inet.tcp.keepinit=5000
net.inet.tcp.maxtcptw=65536
net.inet.tcp.msl=5000
net.inet.tcp.recvbuf_auto=0
net.inet.tcp.recvspace=65536
net.inet.tcp.sendbuf_auto=0
net.inet.tcp.sendspace=131072
net.inet.tcp.syncookies=1
net.inet.tcp.tso=0
net.inet.udp.blackhole=1
net.inet.udp.recvspace=32768
net.isr.direct=1
net.route.netisr_maxqlen=1024
vfs.ufs.dirhash_maxmem=100000000
Если все прошло нормально, то зайдя в админку youserver.com:5280/admin/nodes/ в Running Nodes будут обе ноды.
mod_admin_extra значительно расширяет список команд, которые можно передать через ejabberdctl. Если вы оставили активным модуль ejabberd_xmlrpc (который стал встроен в ejabberd с 13-й версии), то команды jabber-серверу можно передавать и через XmlRPC. Мы, к примеру, управляем ростером, группами, vcard'ами и прочим через специальные worker'ы, написанные на php. Но, по сути, подключаться к xmlrpc можно из чего угодно.
Что касается потребляемых ресурсов, то для 100 тысяч подключенных пользователей требуется где-то под 25-30 Gb памяти (это при хранении большинства данных в mysql, т.е. чисто на обслуживание подключенных клиентов). Если хранить данные в mnesia, то цифра легко может дойти до 100 Gb и больше, но тут все зависит от количества пользователей и данных в базе.
К сожалению, в сети очень мало примеров успешных инсталляций ejabberd, которые работают с десятками тысяч подключенных пользователей. Лично я натыкался лишь на «слухи» о том, что значительно патченный ejabberd — основа сервисов WhatsApp. Да и, сам по себе, erlang — отдельная песня, к которой бывает не так просто найти подход :) Mailing-листы ejabberd тоже в полумертвом состоянии, и проконсультироваться с кем-то о возможных проблемах на high-load проблемно, поэтому многое приходится изучать с горьким опытом. Радует, что ejabberd сейчас довольно активно развивается (по сравнению с периодом до второй половины 2013 года), появляется новый функционал. В этом году появились несколько major-контрибуторов из сообщества, которые регулярно правят баги, оставшиеся с 2.х версий или вновь приобретенные.
Рад буду найти «сообщников», которые используют ejabberd в своих сервисах — быть может сможем продуктивно поделиться опытом друг с другом!
P.S. Буду благодарен за указание недочетов (желательно в личку) и рад любым комментариям. Спасибо!
