Отказоустойчивый производительный кластер для Java приложений

Со времени запуска проекта прошло некоторое время и настало время наращивать вычислительные мощности для работы приложения. Было принято решение построить для этого высокодоступный отказоустойчивый и производительный кластер, который в дальнейшем можно будет легко масштабировать. Таким образом нам надо настроить отказоустойчивый кластер для распределения запросов между серверами приложений.

Для этого мы будем использовать 4 сервера на Linux CentOS 5.5, а так же Apache, Tomcat6, mod_jk, heartbeat.
web1, web2 сервера — для распределения запросов средствами Apache и отказоустойчивости средствами Heartbeat. app1, app2 сервера — Tomcat сервера для Java-приложения.
Установка софта:

[root@web1 opt]$ yum -y install httpd heartbeat
[root@web1 opt]$ chkconfig heartbeat on

Для того чтобы Apache на серверах web1 и web2 научить распределять нагрузку между серверами app1 и app2, нужно к Apache подключить модуль mod_jk.
Скачиваем mod_jk для своей версии Apache, переименовываем и перемещаем его в директорию /etc/httpd/modules.

[root@web1 opt]$ wget www.apache.org/dist/tomcat/tomcat-connectors/jk/binaries/linux/jk-1.2.31/i386/mod_jk-1.2.31-httpd-2.2.x.so
[root@web1 opt]$ mv mod_jk-1.2.31-httpd-2.2.x.so /etc/httpd/modules/mod_jk.so

Делаем теже действия для web2 сервера.

Так как в репозитории нет последней стабильной версии Tomcat, то я предпочитаю его скачивать с зеркала.

[root@app1 opt]$ wget apache.strygunov.com/tomcat/tomcat-6/v6.0.29/bin/apache-tomcat-6.0.29.tar.gz
[root@app1 opt]$ tar xvfz apache-tomcat-6.0.29.tar.gz
[root@app1 opt]$ mv apache-tomcat-6.0.29 tomcat
[root@app1 opt]$ ln -s /opt/tomcat/bin/catalina.sh /etc/init.d/tomcat

Делаем теже действия для app2 сервера.

Настройка Heartbeat:

[root@web1 opt]$ touch /etc/ha.d/authkeys
[root@web1 opt]$ touch /etc/ha.d/ha.cf
[root@web1 opt]$ touch /etc/ha.d/haresources

Выставим параметр на чтение только для пользователя root на файл /etc/ha.d/authkeys, иначе heartbeat не запустится.

[root@web1 ha.d]$ chmod 600 /etc/ha.d/authkeys

И добавим в его 2 строки. Файл должен быть идентичным на обоих узлах.

[root@web1 ha.d]$ nano authkeys

auth 2
2 sha1 your-password

Делаем теже действия для web2 сервера.

Отредактируем файл /etc/ha.d/ha.cf. Файл должен быть идентичным на обоих узлах.

[root@web1 ha.d]$ nano ha.cf

logfacility local0
keepalive 2
deadtime 10
initdead 120
bcast eth0
udpport 694
auto_failback on
node web1
node web2
respawn hacluster /usr/lib/heartbeat/ipfail
use_logd yes
log?le /var/log/ha.log
debug?le /var/log/ha-debug.log

Делаем теже действия для web2 сервера.

Отредактируем файл /etc/ha.d/haresources. Файл должен быть идентичным на обоих узлах.

[root@web1 ha.d]$ nano haresources

web1 192.168.0.1 httpd # общий ip для обращения из браузера.

Делаем теже действия для web2 сервера.

Настройка балансировки:

В файл /etc/httpd/conf/httpd.conf добавляем строки:

[root@web1 conf]$ nano httpd.conf

LoadModule jk_module modules/mod_jk.so

JkWorkersFile conf/workers.properties
JkLogFile logs/mod_jk.log
JkLogLevel info
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
JkRequestLogFormat "%w %V %T"

В секции DocumentRoot добавляем следующие две строки:

JkMount /*.jsp loadbalancer
JkMount /servlet/* loadbalancer

Делаем теже действия для web2 сервера.

В папке /etc/httpd/conf создаем файл workers.properties.

[root@web1 conf]$ touch workers.properties

Добавляем в его следующие строки:

worker.list=app1, app2, loadbalancer

worker.app1.port=10010
worker.app1.host=192.168.1.1
worker.app1.type=ajp13
worker.app1.lbfactor=1

worker.app2.port=10020
worker.app2.host=192.168.1.2
worker.app2.type=ajp13
worker.app2.lbfactor=1

worker.loadbalancer.type=lb
worker.loadbalancer.balanced_workers=app1, app2

Делаем теже действия для web2 сервера.

В /opt/tomcat/conf/server.xml обоих Tomcat'ов настраиваем порты( все порты должны быть разными):

[root@app1 conf]$ nano server.xml

<server port=«8005» ...>

<! — Комментируется HTTP коннектор, т.к. нам нужен только AJP коннектор
/>
-->

/>

[root@app2 conf]$ nano server.xml

<server port=«8006» ...>

<! — Комментируется HTTP коннектор, т.к. нам нужен только AJP коннектор
/>
-->

/>

Настройка репликации сессий

Для того, чтобы при падении одного из Tomcat серверов не была уничтожена сессия пользователя, имеет смысл настроить репликацию сессий между Tomcat серверами. Для этого добавляем в /opt/tomcat/conf/server.xml в секции "<Еngine name=«Catalina» defaultHost=«localhost»>" всех Tomcat'ов следующие строки:

[root@app1 conf]$ nano server.xml

<еngine name=«Catalina» defaultHost=«localhost» debug=«0» jvmRoute=«appt1»>

<receiver
className=«org.apache.catalina.cluster.tcp.ReplicationListener»
tcpListenAddress=«auto»
tcpListenPort=«4001»
tcpSelectorTimeout=«100»
tcpThreadCount=«6»/>
/>

[root@app2 conf]$ nano server.xml

<еngine name=«Catalina» defaultHost=«localhost» debug=«0» jvmRoute=«app2»>

<receiver
className=«org.apache.catalina.cluster.tcp.ReplicationListener»
tcpListenAddress=«auto»
tcpListenPort=«4002»
tcpSelectorTimeout=«100»
tcpThreadCount=«6»/>
/>

Запускаем сервисы:

[root@web1 /]$ service heartbeat start
[root@web2 /]$ service heartbeat start
[root@app1 /]$ /etc/init.d/tomcat
[root@app2 /]$ /etc/init.d/tomcat

На этом настройка отказоустойчивого и производительного кластера для Java-сервлетов закончена. Мы добились отказоустойчивости и масштабируемой производительности, что позволит нам с легкостью добавлять новые узлы в кластер в случае нехватки производительности.


0 комментариев

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.