Настройка кластеризации и репликации сеанса в Tomcat#
Чтобы включить кластеризацию в Tomcat, достаточно добавить элемент <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> в <Engine> или <Host>.
Использование данной конфигурации включает репликацию сессий между всеми node кластера с использованием DeltaManager. Каждая сессия реплицируется на все остальные node. Такой подход хорошо работает для небольших кластеров (до 4 node), но не рекомендуется для больших кластеров. При использовании DeltaManager Tomcat будет реплицировать сессии на все node, даже на те, где приложение не развернуто.
Чтобы избежать проблем, рекомендуется использовать BackupManager. В отличие от DeltaManager, BackupManager реплицирует данные сессии только на один резервный node, и только на те node, где приложение развернуто.
Важные параметры по умолчанию:
Multicast-адрес;
Multicast-порт (порт и адрес определяют членство в кластере);
IP-адрес для рассылки:
java.net.InetAddress.getLocalHost().getHostAddress();TCP-порт для прослушивания сообщений репликации: первый доступный серверный сокет в диапазоне
4000-4100;Listener: настроен как
ClusterSessionListener;Два Interceptor: настроены
TcpFailureDetectorиMessageDispatchInterceptor.
Пример конфигурации:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
channelSendOptions="8">
<Manager className="org.apache.catalina.ha.session.DeltaManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"/>
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<Membership className="org.apache.catalina.tribes.membership.McastService"
address="<IP_address>"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="auto"
port="4000"
autoBind="100"
selectorTimeout="5000"
maxThreads="6"/>
<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
</Sender>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>
</Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=""/>
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
Безопасность#
Реализация кластера в Tomcat предполагает использование безопасной и доверенной сети для всего сетевого трафика, связанного с кластером. Небезопасно запускать кластер в ненадежной или незащищенной сети.
Для обеспечения безопасной и доверенной сети можно использовать следующие варианты:
Частная локальная сеть (LAN);
Виртуальная частная сеть (VPN);
IPSEC.
Компонент EncryptInterceptor обеспечивает конфиденциальность и целостность данных, но он не защищает от всех рисков, связанных с запуском кластера Tomcat в ненадежной сети, особенно от атак типа DoS.
Настройка репликации#
Чтобы настроить репликацию сессий в Tomcat, выполните следующие шаги:
Все атрибуты сессии должны реализовывать интерфейс
java.io.Serializable.Элемент
<Cluster>в файлеserver.xmlдолжен быть раскомментирован.Если определены пользовательские
valveдля кластера, убедитесь, что также определенReplicationValveвнутри элемента<Cluster>вserver.xml.Если экземпляры Tomcat работают на одной машине, убедитесь, что атрибут
Receiver.portуникален для каждого экземпляра. В большинстве случаев Tomcat автоматически определяет доступные порты в диапазоне4000-4100.Убедитесь, что в
web.xmlесть элемент<distributable/>.Если используете
mod_jk, убедитесь, что атрибутjvmRouteзадан в элементе<Engine>:<Engine name="Catalina" jvmRoute="node01">.Убедитесь, что все node работают в одинаковом времени и синхронизируются с сервисом NTP.
Убедитесь, что балансировщик нагрузки настроен на режим
sticky session mode.
Включение репликации#
Для включения репликации сессий в Tomcat можно использовать три различных подхода:
Использование сохранения сессий (
PersistenceManager) и хранение сессий в общей файловой системе (FileStore).Использование сохранения сессий (
PersistenceManager) и хранение сессий в общей базе данных (JDBCStore).Использование репликации в памяти с помощью
SimpleTcpCluster, который поставляется с Tomcat (библиотекиcatalina-tribes.jarиcatalina-ha.jar).
Tomcat может выполнять репликацию состояния сессии «все-ко-всем» с использованием DeltaManager или репликацию только на один резервный node с использованием BackupManager. Данная репликация эффективна только для небольших кластеров. Для больших кластеров рекомендуется использовать BackupManager, где сессия хранится только на одном резервном node.
В настоящее время можно использовать атрибут domain в mod_jk для создания разделов кластера, что позволяет создать более масштабируемое решение с DeltaManager (для этого нужно настроить domain). Чтобы уменьшить сетевой трафик в среде, можно разделить кластер на меньшие группы, используя разные multicast-адреса для каждой группы.
Информация о кластере#
Членство в кластере устанавливается с помощью multicast-сообщений (heartbeats). Таким образом, если нужно разделить кластер, измените IP-адрес или порт multicast в элементе <Membership>. Сообщение содержит IP-адрес node и TCP-порт, который Tomcat использует для трафика репликации. Все данные передаются по TCP.
ReplicationValve используется для определения завершения запроса и инициации репликации, если это необходимо. Данные реплицируются только в случае изменения сессии (например, при вызове setAttribute или removeAttribute).
Одним из важных аспектов производительности является выбор между синхронной и асинхронной репликацией. В синхронном режиме запрос не завершается до тех пор, пока реплицированная сессия не будет отправлена и восстановлена на всех других node кластера. Синхронный или асинхронный режим настраивается с помощью флага channelSendOptions, который представляет собой числовое значение. По умолчанию для комбинации SimpleTcpCluster/DeltaManager используется значение 8, что соответствует асинхронному режиму.
Привязка сессии после сбоя к резервному node#
Если mod_jk используется без sticky sessions или в случае сбоя, идентификатор сессии (session id) необходимо изменить, так как он ранее содержал идентификатор (jvmRoute) предыдущего Tomcat. Для решения этой проблемы используется JvmRouteBinderValve.
JvmRouteBinderValve перезаписывает идентификатор сессии, чтобы гарантировать, что следующий запрос не будет перенаправлен на случайный node. valve перезаписывает значение JSESSIONID в cookie-файлы.
С помощью атрибута sessionIdAttribute можно изменить имя атрибута запроса, который содержит старый идентификатор сессии. По умолчанию это org.apache.catalina.ha.session.JvmRouteOriginalSessionID.
Можно включить данный режим переключения через JMX перед отключением node на всех резервных узлах. Установите enable=true на всех JvmRouteBinderValve, отключите worker в mod_jk, затем отключите node и перезапустите его. После этого включите worker в mod_jk и отключите JvmRouteBinderValve. Этот подход означает, что мигрируют только запрошенные сессии.
Мониторинг кластера с помощью JMX#
Мониторинг является важной задачей при использовании кластера. Некоторые объекты кластера представляют собой JMX MBeans.
Для настройки JMX для мониторинга добавьте следующие параметры в скрипт запуска:
set CATALINA_OPTS=\
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=%my.jmx.port% \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false
Имя |
Описание |
MBean ObjectName (Engine) |
MBean ObjectName (Host) |
|---|---|---|---|
|
Полный элемент кластера |
|
|
|
Управление сессиями и обработка репликации сессий |
|
|
|
Управление процессом развертывания приложения на всех node кластера |
Не поддерживается |
|
|
Предоставление node в кластере |
|
|
|
Управление репликацией на резервные node |
|
|
|
|
|
|