Ejabberd 14.x на FreeBSD 10: установка і базова настройка

Доброго часу доби!

Невелику передмову: не так давно побачили світ 13-я, а за нею в цьому році і 14-я версії ejabberd. Process One вирішили змінити схему версионирования в силу ряду причин і версії 2.x зараз вже вважаються застарілими. Новий ejabberd поділився на дві гілки — ejabberd Community Server і ejabberd Business Edition і почав досить активно розвиватися.

В нашому випадку, в якості системи була обрана FreeBSD, так як потрібно підтримувати досить велика кількість з'єднань на ноду (~100к).

На установці системи сенсу зупинятися не бачу, тому під катом відразу перейдемо до налаштування.

Частину своїх даних 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/src

git clone git://github.com/erlang/otp.git


Збираємо, ставимо його:
cd /usr/local/src/otp

autoconf-f

./configure --prefix=/usr/local --enable-kernel-poll --with-ssl --enable-threads --with-odbc --enable-smp-support 

gmake

gmake install


Далі качаємо ejabberd і ejabberd-contrib:
cd /usr/local/src

git clone git://github.com/processone/ejabberd.git

git clone git://github.com/gamenet/ejabberd-contrib.git


Створюємо користувача ejabberd, в якості домашньої директорії вказуємо /var/lib/ejabberd.

Збираємо і ставимо ejabberd:
cd /usr/local/src/ejabberd

autoconf-f

./configure --enable-mysql=yes --enable-odbc=yes --enable-lager=yes --prefix=/usr/local --localstatedir=/var --enable-user=ejabberd

gmake && 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.sh

cp ./ebin/mod_admin_extra.beam /usr/local/lib/ejabberd/ebin/


Етап 2:

Основний конфігураційний файл ejabberd.yml рясніє прикладами та коментарями розробників, тому встановити його не складно. В yaml-конфігураційних файлах важлива табуляція, редактор хабра у мене її з'їв, тому будьте уважні! Зупинюся лише на деяких параметрах:

hosts:

- "youserver.com"


У секції ejabberd_c2s:
backlog: 1024 


Для зовнішньої авторизації:
auth_method: external

extauth_program: "/usr/local/bin/<ваш_скрипт>.php"

extauth_instances: 12

extauth_cache: 72000


Для підключення до mysql:
odbc_type: mysql

odbc_server: "mysql_server_ip"

odbc_database: "dbname"

odbc_username: "username"

odbc_password: "password"

odbc_pool_size: 16

odbc_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=524288

FIREWALL_WINDOW=4200-4210

ERL_PROCESSES=5000000

ERL_MAX_ETS_TABLES=262144

ERLANG_NODE=ejabberd@node1


Йдемо на mysql-сервер, створюємо там базу і заливаємо в неї дамп з mysql.sql з папки sql исходников ejabberd.

Запускаємо!
su - ejabberd

ejabberdctl start


Створюємо користувача admin:
ejabberdctl register admin yourserver.com password


Етап 3:
Для створення кластера беремо ще один сервер і проробляємо процедури, описані вище.
Щоб реплікація між нодами працювала коректно (та й взагалі щоб зібрати кластер) потрібно, щоб ноди могли з'єднуватися один з одним по порту 4369 і тими портами, що ви вказали в FIREWALL_WINDOW.

Копіюємо файл /var/lib/ejabberd/.erlang_cookie c першої ноди на другу і якщо проблем із з'єднаннями між нодами немає, то збираємо кластер:
su - ejabberd

erl-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. І так, не судіть строго — це моя перша стаття на Хабре, буду вдячний на зазначення недоліків, та й взагалі будь-яких коментарів. Спасибі!


Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.