Репликация кластеров / сеансов Tomcat не реплицируется должным образом

17

Я настраиваю кластеризацию / репликацию на Tomcat 7 на своей локальной машине, чтобы оценить ее для использования с моей средой / кодовой базой.

Настройка

У меня есть два одинаковых сервера tomcat в каталогах сестер, работающих на разных портах. У меня есть httpd, прослушивающий два других порта и подключение к двум экземплярам tomcat как VirtualHosts. Я могу получать доступ и взаимодействовать с обоими средами на настроенных портах; все работает как ожидалось.

Серверы tomcat имеют такую ​​кластеризацию, что и в server.xml:

   <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="228.0.0.4"
                    port="45564"
                    frequency="500"
                    dropTime="3000"/>
        <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                  address="auto"
                  port="4001"
                  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.MessageDispatch15Interceptor"/>
      </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.JvmRouteSessionIDBinderListener"/>
      <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
   </Cluster>

, и я добавил дистрибутивный тег к самому началу web.xml:

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
  version="3.0">
  <distributable />

  (lots more...)

</web-app>

Что работает

Когда серверы запускаются, они записывают

Sep 16, 2013 1:44:23 PM org.apache.catalina.ha.tcp.SimpleTcpCluster startInternal
INFO: Cluster is about to start
Sep 16, 2013 1:44:23 PM org.apache.catalina.tribes.transport.ReceiverBase getBind
FINE: Starting replication listener on address:10.0.0.100
Sep 16, 2013 1:44:23 PM org.apache.catalina.tribes.transport.ReceiverBase bind
INFO: Receiver Server Socket bound to:/10.0.0.100:4001
Sep 16, 2013 1:44:23 PM org.apache.catalina.tribes.membership.McastServiceImpl setupSocket
INFO: Setting cluster mcast soTimeout to 500
Sep 16, 2013 1:44:23 PM org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers
INFO: Sleeping for 1000 milliseconds to establish cluster membership, start level:4
Sep 16, 2013 1:44:24 PM org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers
INFO: Done sleeping, membership established, start level:4
Sep 16, 2013 1:44:24 PM org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers
INFO: Sleeping for 1000 milliseconds to establish cluster membership, start level:8
Sep 16, 2013 1:44:25 PM org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers
INFO: Done sleeping, membership established, start level:8

Когда второй сервер запускается, первый регистрирует

Sep 16, 2013 2:17:30 PM org.apache.catalina.tribes.group.interceptors.TcpFailureDetector messageReceived
FINE: Received a failure detector packet:ClusterData[src=org.apache.catalina.tribes.membership.MemberImpl[tcp://{10, 0, 0, 100}:4000,{10, 0, 0, 100},4000, alive=112208, securePort=-1, UDP Port=-1, id={118 6 107 -67 88 98 72 95 -73 41 4 -108 58 -5 -127 -41 }, payload={}, command={}, domain={}, ]; id={25 110 120 -2 -25 6 78 -97 -84 -34 2 -11 49 -62 -8 -56 }; sent=2013-09-16 14:17:30.139]
Sep 16, 2013 2:17:30 PM org.apache.catalina.tribes.transport.nio.NioReplicationTask remoteEof
FINE: Channel closed on the remote end, disconnecting
Sep 16, 2013 2:17:30 PM org.apache.catalina.tribes.membership.McastServiceImpl memberDataReceived
FINE: Mcast add member org.apache.catalina.tribes.membership.MemberImpl[tcp://{10, 0, 0, 100}:4001,{10, 0, 0, 100},4001, alive=1010, securePort=-1, UDP Port=-1, id={82 -45 -109 -56 -110 -5 78 -10 -103 61 -40 -59 -36 -79 104 120 }, payload={}, command={}, domain={}, ]
Sep 16, 2013 2:17:30 PM org.apache.catalina.ha.tcp.SimpleTcpCluster memberAdded
INFO: Replication member added:org.apache.catalina.tribes.membership.MemberImpl[tcp://{10, 0, 0, 100}:4001,{10, 0, 0, 100},4001, alive=1011, securePort=-1, UDP Port=-1, id={82 -45 -109 -56 -110 -5 78 -10 -103 61 -40 -59 -36 -79 104 120 }, payload={}, command={}, domain={}, ]

, а когда один выключается, другой регистрирует

Sep 16, 2013 2:28:05 PM org.apache.catalina.tribes.membership.McastServiceImpl memberDataReceived
FINE: Member has shutdown:org.apache.catalina.tribes.membership.MemberImpl[tcp://{10, 0, 0, 100}:4001,{10, 0, 0, 100},4001, alive=422279, securePort=-1, UDP Port=-1, id={54 43 17 -9 13 -11 72 -63 -107 -78 -8 65 -21 -77 115 88 }, payload={}, command={66 65 66 89 45 65 76 69 88 ...(9)}, domain={}, ]
Sep 16, 2013 2:28:05 PM org.apache.catalina.tribes.group.interceptors.TcpFailureDetector memberDisappeared
INFO: Verification complete. Member disappeared[org.apache.catalina.tribes.membership.MemberImpl[tcp://{10, 0, 0, 100}:4001,{10, 0, 0, 100},4001, alive=422279, securePort=-1, UDP Port=-1, id={54 43 17 -9 13 -11 72 -63 -107 -78 -8 65 -21 -77 115 88 }, payload={}, command={66 65 66 89 45 65 76 69 88 ...(9)}, domain={}, ]]
Sep 16, 2013 2:28:05 PM org.apache.catalina.ha.tcp.SimpleTcpCluster memberDisappeared
INFO: Received member disappeared:org.apache.catalina.tribes.membership.MemberImpl[tcp://{10, 0, 0, 100}:4001,{10, 0, 0, 100},4001, alive=422279, securePort=-1, UDP Port=-1, id={54 43 17 -9 13 -11 72 -63 -107 -78 -8 65 -21 -77 115 88 }, payload={}, command={66 65 66 89 45 65 76 69 88 ...(9)}, domain={}, ]

, поэтому я знаю, что они знают друг о друге.

Наконец, когда я использую кластер / Operations MBean в jconsole, чтобы попытаться установить свойство «foo» на «bar», jconsole сообщает «метод успешно вызван», а журналы сервера

Sep 16, 2013 2:30:18 PM org.apache.catalina.ha.tcp.SimpleTcpCluster setProperty
WARNING: Dynamic setProperty(foo,value) has been disabled, please use explicit properties for the element you are trying to identify

Я не слишком беспокоюсь об этой ошибке; в основном для демонстрации того, что setProperty создает оператор журнала.

Что не работает

Насколько я могу судить, никакая информация о сеансе не реплицируется в моем приложении.

Менеджер tomcat перечисляет сеансы, запущенные на сервере, который он контролирует, а не другой в кластере.

У меня создается впечатление, что всякий раз, когда приложение вызывает HttpSession.setAttribute, этот атрибут должен быть реплицирован на другие узлы кластера, и я ожидаю, что какая-то запись этого будет записана в журнал. Мое приложение включает эту строку:

   public static void saveBillingInfo(IPageContext pageContext, BillingInfo billingInfo)
   {    
      pageContext.getSession().setAttribute("billingInfo", billingInfo);
      //etc...
   }

, где BillingInfo - это класс Serializable, содержащий только одно поле, HashMap информации о платежной информации.

Никакие операторы журналов не записываются, если эта или любая другая строка обрабатывается, и я не вижу никаких доказательств того, что информация сеанса фактически разделяется.

Любые предложения или дальнейшие вопросы приветствуются.

    
задан nvioli 16.09.2013 в 20:41
источник
  • Используете ли вы jk_mod? Если да, у вас есть атрибут jvmRoute, указанный в теге Engine? На любом веб-сервере нажмите на страницы менеджера: xxx.com \ manager \ html и посмотрите, какие сеансы создаются. Вы должны уметь видеть обе сессии Tomcat, какой бы узел вы ни проверяли. –  Darius X. 16.09.2013 в 21:42
  • nope, я использую mod_proxy. –  nvioli 16.09.2013 в 21:45
  • У вас есть атрибут jvmRoute, указанный в теге Engine? На любом веб-сервере нажмите на страницы менеджера: xxx.com \ manager \ html и посмотрите, какие сеансы создаются. Вы должны уметь видеть обе сессии Tomcat, какой бы узел вы ни проверяли –  Darius X. 16.09.2013 в 21:48
  • В документах упоминается только о пометке jvmRoute в теге engine, если я использую mod_jk, поэтому я пропустил этот шаг. –  nvioli 16.09.2013 в 22:05
  • , а менеджер показывает только информацию высокого уровня о сеансах: Активные сеансы: 0 Количество сеансов: 0 Максимальное количество активных сеансов: 0 Отклоненные сеансовые создания: 0 Истекшие сеансы: 0 Длительность активного сеанса: 0 с Среднее время сеанса сеанса: 0 с Время обработки: 1 мс. Кажется, я видел сеансы (например, count> 0) раньше, но они остаются на уровне 0 на данный момент. –  nvioli 16.09.2013 в 22:06
Показать остальные комментарии

5 ответов

28

У нас была эта идентичная проблема. Хотя он нигде не документирован, для меня это решило просто переместить & lt; Manager & gt; tag из server.xml в глобальный context.xml (вывод его из группы & lt; Server & gt; ... & lt; Cluster & gt; ... и в группу & lt; Контекст & gt;). Как только мы это сделали, все «магически» начало работать. Это применимо только к Tomcat 7 ... Tomcat 6 отлично работал с настройкой, описанной выше (и, как описано в документации).

<Context>
    <Manager className="org.apache.catalina.ha.session.DeltaManager"
             expireSessionsOnShutdown="false"
             notifyListenersOnReplication="true" />
</Context>

Теперь просто удалите & lt; Manager & gt; тега из вашей группы кластеров в server.xml, и все готово.

    
ответ дан Jason 15.10.2013 в 23:33
источник
  • Спасибо Джейсону и nvioli! Вы сделали мой день! –  walv 28.05.2014 в 15:28
  • Я тоже. Большое спасибо!! –  kurikintoki 11.09.2014 в 07:34
  • Спасибо, это полезно. –  asifaftab87 13.01.2016 в 11:18
  • Но почему? У меня два разных кластера. В одном из них все работает с помощью <Manager> внутри группы <Cluster>. Другой не работает, и работает, только если, как указано здесь, я помещаю <Manager> внутри файла context.xml. Я не могу понять. –  alciregi 05.02.2016 в 10:39
0

на сервере.xml просто добавьте:

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
             channelSendOptions="6"/>  

и в вашем контексте .xml:

<Manager className="org.apache.catalina.ha.session.DeltaManager"
         expireSessionsOnShutdown="false"
         notifyListenersOnReplication="true" />

это сработало для меня, я использую Tomcat 7 и Tomcat 8

    
ответ дан Fabian Mejia 18.06.2015 в 23:47
источник
0

Нашим решением было добавить тег <distributable/> в файл WEB-INF/web.xml в элементе <web-app> . Не уверен, почему это сработало для нас не для OP.

Кстати, решение Джейсона тоже сработало для нас.

    
ответ дан David I 08.04.2016 в 22:35
источник
0

Если вы хотите включить кластеризацию для определенного развернутого приложения, вы можете использовать нижеприведенный пример

server.xml

  <Host name="localhost"  appBase="webapps"
        unpackWARs="true" autoDeploy="true">

      <Channel className="org.apache.catalina.tribes.group.GroupChannel">
        <Membership className="org.apache.catalina.tribes.membership.McastService"
                    address="228.0.0.4"
                    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.MessageDispatch15Interceptor"/>
      </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.JvmRouteSessionIDBinderListener"/>
      <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>

      <Manager className="org.apache.catalina.ha.session.DeltaManager"
       expireSessionsOnShutdown="false"
       notifyListenersOnReplication="true"/>

    <Resource auth="Container" driverClassName="oracle.jdbc.OracleDriver" factory="com.atomikos.tomcat.EnhancedTomcatAtomikosBeanFactory" minPoolSize="4" maxPoolSize="50" name="jdbc/myoracle/myconect" password="sdfhsfghsgfsfg" type="com.atomikos.jdbc.nonxa.AtomikosNonXADataSourceBean" uniqueResourceName="uniresource" url="jdbc:oracle:thin:@10.10.10.10.:1521:abc" user="user"/>
    </Context>
    
ответ дан Thanh Nguyen 27.09.2016 в 06:05
источник
0

В соответствии с документами Tomcat вам нужно сделать один из этих двух (НЕ оба):

  1. Укажите в web.xml <distributable/> , чтобы включить кластеризацию и использовать значение <Manager> по умолчанию, указанное в файле server.xml или ...

  2. Добавьте <Manager> на уровне приложения внутри context.xml

ответ дан user6649882 28.07.2016 в 15:13
источник