JDBC主/副本

如果您使用的是纯JDBC而不是高性能日志,那么您通常将数据库作为单一故障点和持久性引擎。如果您没有真正的高性能需求,这种方法会非常有意义,因为您有一个单独的持久性引擎来备份和管理等。

启动

当只使用JDBC作为数据源时,可以使用主/副本方法,如图所示运行任意数量的代理。启动时,一个主代理获取代理数据库中的独占锁-所有其他代理都是副本并暂停等待独占锁。

../../../_images/Startup.png

客户端应使用故障转移传输连接到可用的代理。e、 g.使用类似以下故障转移的URL:(tcp://broker1:61616,tcp://broker2:61616,tcp://broker3:61616)只有主代理启动其传输连接器,因此客户端只能连接到主代理。

主要故障

如果主服务器断开与数据库的连接或释放独占锁,则它将立即关闭。如果一个主服务器关闭或发生故障,另一个副本将获得锁,因此拓扑将切换到下图

../../../_images/MasterFailed.png

另一个副本服务器立即获取数据库的独占锁,然后开始成为主服务器,启动其所有传输连接器。客户端断开与已停止的主代理的连接,然后故障转移传输尝试连接到可用的代理-其中唯一可用的代理是新的主代理。主代理重启在任何时候您可以重启加入集群的其他代理,并在主代理关闭或发生故障时作为副本启动,以等待成为主代理。因此,在重新启动旧的主节点后将创建以下拓扑...

配置JDBC主/副本

../../../_images/MasterRestarted.png

默认情况下,如果您使用<jdbpersistenceadapter/>来避免高性能日志,那么缺省情况下您将使用JDBC Primary/Replica。您只需要运行多个代理并将客户端uri指向它们就可以获得主/副本。这是因为它们都尝试在数据库中的共享表上获取独占锁,只有一个会成功。

下面的示例演示如何在JDBC主/副本模式下配置ActiveMQ代理

<beans>

  <!-- Allows us to use system properties as variables in this configuration file -->
  <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>

  <broker xmlns="http://activemq.apache.org/schema/core">

    <destinationPolicy>
      <policyMap><policyEntries>

          <policyEntry topic="FOO.>">
            <dispatchPolicy>
              <strictOrderDispatchPolicy />
            </dispatchPolicy>
            <subscriptionRecoveryPolicy>
              <lastImageSubscriptionRecoveryPolicy />
            </subscriptionRecoveryPolicy>
          </policyEntry>

      </policyEntries></policyMap>
    </destinationPolicy>


    <persistenceAdapter>
        <jdbcPersistenceAdapter dataDirectory="${activemq.base}/activemq-data"/>

        <!--
        <jdbcPersistenceAdapter dataDirectory="activemq-data" dataSource="#oracle-ds"/>
        -->
    </persistenceAdapter>

    <transportConnectors>
      <transportConnector name="default" uri="tcp://localhost:61616"/>
    </transportConnectors>

  </broker>

  <!--  This xbean configuration file supports all the standard spring xml configuration options -->

  <!-- Postgres DataSource Sample Setup -->
  <!--
  <bean id="postgres-ds" class="org.postgresql.ds.PGPoolingDataSource">
    <property name="serverName" value="localhost"/>
    <property name="databaseName" value="activemq"/>
    <property name="portNumber" value="0"/>
    <property name="user" value="activemq"/>
    <property name="password" value="activemq"/>
    <property name="dataSourceName" value="postgres"/>
    <property name="initialConnections" value="1"/>
    <property name="maxConnections" value="10"/>
  </bean>
  -->

  <!-- MySql DataSource Sample Setup -->
  <!--
  <bean id="mysql-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost/activemq?relaxAutoCommit=true"/>
    <property name="username" value="activemq"/>
    <property name="password" value="activemq"/>
    <property name="poolPreparedStatements" value="true"/>
  </bean>
  -->

  <!-- Oracle DataSource Sample Setup -->
  <!--
  <bean id="oracle-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
    <property name="url" value="jdbc:oracle:thin:@localhost:1521:AMQDB"/>
    <property name="username" value="scott"/>
    <property name="password" value="tiger"/>
    <property name="poolPreparedStatements" value="true"/>
  </bean>
  -->

  <!-- Embedded Derby DataSource Sample Setup -->
  <!--
  <bean id="derby-ds" class="org.apache.derby.jdbc.EmbeddedDataSource">
    <property name="databaseName" value="derbydb"/>
    <property name="createDatabase" value="create"/>
  </bean>
  -->

</beans>