Ejabberd 14.x на FreeBSD 10: установка и базовая настройка
Доброго времени суток! Небольшое предисловие: не так давно увидели свет 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-supportgmakegmake 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: odbcmod_muc: db_type: odbcmod_offline: db_type: odbcmod_privacy: db_type: odbcmod_private: db_type: odbcmod_roster: db_type: odbcmod_shared_roster: db_type: odbcmod_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. Буду благодарен за указание недочетов (желательно в личку) и рад любым комментариям. Спасибо!