1. 参考文档地址
http://activemq.apache.org/masterslave.html
2. 服务器软件
apache-activemq-5.1.0
2.1 特性及优势
1、实现JMS1.1规范,支持J2EE1.4以上
2、可运行于任何jvm和大部分web容器(ActiveMQ works great in any JVM)
3、支持多种语言客户端(java, C, C++, AJAX, ACTIONSCRIPT等等)
4、支持多种协议(stomp,openwire,REST)
5、良好的spring支持(ActiveMQ has great Spring Support)
6、速度很快,JBossMQ的十倍(ActiveMQ is very fast; often 10x faster than JBossMQ.)
7、与OpenJMS、JbossMQ等开源jms provider相比,ActiveMQ有Apache的支持,持续发展的优势明显。
2.2 集群方式
在一个网络内运行多个brokers或者stand alone brokers时存在一个问题,这就是消息在物理上只被一个broker持有,因此当某个broker失效,那么你只能等待直到它重启后,这个broker上的消息才能够被继续发送(如果没有设置持久化,那么在这种情况下,消息将会丢失)。Master Slave 背后的想法是,消息被复制到slave broker,因此即使master broker遇到了像硬件故障之类的错误,你也可以立即切换到slave broker而不丢失任何消息。
Master Slave是目前ActiveMQ推荐的高可靠性和容错的解决方案。以下是几种不同的类型:
Master Slave Type
Requirements
Pros
Cons
Pure Master Slave
None
No central point of failure
Requires manual restart to bring back a failed master and can only support 1 slave
Shared File System Master Slave
A Shared File system such as a SAN
Run as many slaves as required. Automatic recovery of old masters
Requires shared file system
JDBC Master Slave
A Shared database
Run as many slaves as required. Automatic recovery of old masters
Requires a shared database. Also relatively slow as it cannot use the high performance journal
2.2.1 Pure Master Slave
Ø Pure Master Slave的工作方式如下:
Slave broker消费master broker上所有的消息状态,例如消息、确认和事务状态等。只要slave broker连接到了master broker,它不会(也不被允许)启动任何network connectors或者transport connectors,所以唯一的目的就是复制master broker的状态。
Master broker只有在消息成功被复制到slave broker之后才会响应客户。例如,客户的commit请求只有在master broker和slave broker都处理完毕commit请求之后才会结束。
当master broker失效的时候,slave broker有两种选择,一种是slave broker启动所有的network connectors和transport connectors,这允许客户端切换到slave broker;另外一种是slave broker停止。这种情况下,slave broker只是复制了master broker的状态。
客户应该使用failover transport并且应该首先尝试连接master broker。例如:
failover://(tcp://masterhost:61616,tcp://slavehost:61616)?randomize=false
设置randomize为false就可以让客户总是首先尝试连接master broker(slave broker并不会接受任何连接,直到它成为了master broker)。
Ø Pure Master Slave具有以下限制:
只能有一个slave broker连接到master broker。
在因master broker失效而导致slave broker成为master之后,之前的master broker只有在当前的master broker(原slave broker)停止后才能重新生效。
Master broker失效后而切换到slave broker后,最安全的恢复master broker的方式是人工处理。首先要停止slave broker(这意味着所有的客户也要停止)。然后把slave broker的数据目录中所有的数据拷贝到master broker的数据目录中。然后重启master broker和slave broker。
Ø Master broker不需要特殊的配置。Slave broker需要进行以下配置:
Xml代码:
<broker masterConnectorURI="tcp://masterhost:62001" shutdownOnMasterFailure="false">
...
<transportConnectors>
<transportConnector uri="tcp://slavehost:61616"/>
</transportConnectors>
</broker>
<broker masterConnectorURI="tcp://masterhost:62001" shutdownOnMasterFailure="false">
...
<transportConnectors>
<transportConnector uri="tcp://slavehost:61616"/>
</transportConnectors>
</broker>
其中的masterConnectorURI用于指向master broker,shutdownOnMasterFailure用于指定slave broker在master broker失效的时候是否需要停止。此外,也可以使用如下配置:
Xml代码 :
<broker brokerName="slave" useJmx="false" deleteAllMessagesOnStartup="true" xmlns="http://activemq.org/config/1.0">
...
<services>
<masterConnector remoteURI= "tcp://localhost:62001" userName="user" password="password"/>
</services>
</broker>
<broker brokerName="slave" useJmx="false" deleteAllMessagesOnStartup="true" xmlns="http://activemq.org/config/1.0">
...
<services>
<masterConnector remoteURI= "tcp://localhost:62001" userName="user" password="password"/>
</services>
</broker>
需要注意的是,笔者认为ActiveMQ5.0版本的Pure Master Slave仍然不够稳定。
客户端连接参数:failover://(tcp://masterhost:61616,tcp://slavehost:61616)?randomize=false
2.2.2 Shared File System Master Slave
如果你使用SAN(存储域网络(Storage Area Network))或者共享文件系统,那么你可以使用Shared File System Master Slave。基本上,你可以运行多个broker,这些broker共享数据目录。当第一个broker得到文件上的排他锁之后,其它的broker便会在循环中等待获得这把锁。客户端使用failover transport来连接到可用的broker。当master broker失效的时候会释放这把锁,这时候其中一个slave broker会得到这把锁从而成为master broker。以下是ActiveMQ配置的一个例子:
Xml代码 :
<broker useJmx="false" xmlns="http://activemq.org/config/1.0">
<persistenceAdapter>
<journaledJDBC dataDirectory="/sharedFileSystem/broker"/>
</persistenceAdapter>
…
</broker>
<broker useJmx="false" xmlns="http://activemq.org/config/1.0">
<persistenceAdapter>
<journaledJDBC dataDirectory="/sharedFileSystem/broker"/>
</persistenceAdapter>
…
</broker>
客户端连接参数:failover:(tcp://broker1:61616,tcp://broker2:61616,tcp://broker3:61616)
2.2.3 JDBC Master Slave
JDBC Master Slave的工作原理跟Shared File System Master Slave类似,只是采用了数据库作为持久化存储。以下是ActiveMQ配置的一个例子:
Xml代码 :
<beans>
<broker xmlns="http://activemq.org/config/1.0" brokerName="JdbcMasterBroker">
...
<persistenceAdapter>
<jdbcPersistenceAdapter dataSource="#mysql-ds"/>
</persistenceAdapter>
</broker>
<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:3306/test?relaxAutoCommit=true"/>
<property name="username" value="username"/>
<property name="password" value="passward"/>
<property name="poolPreparedStatements" value="true"/>
</bean>
</beans>
客户端连接参数:failover:(tcp://broker1:61616,tcp://broker2:61616,tcp://broker3:61616) <beans>
<broker xmlns="http://activemq.org/config/1.0" brokerName="JdbcMasterBroker">
...
<persistenceAdapter>
<jdbcPersistenceAdapter dataSource="#mysql-ds"/>
</persistenceAdapter>
</broker>
<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:3306/test?relaxAutoCommit=true"/>
<property name="username" value="username"/>
<property name="password" value="passward"/>
<property name="poolPreparedStatements" value="true"/>
</bean>
</beans>
2.3 测试结论
参考文档:http://www.51testing.com/?uid-23978-action-viewspace-itemid-143163
1. Pure Master Slaver集群方式重新启动MQ服务后原来连着的用户发送订阅消息,MQ会一直提示”Cannot lookup a connection that had not been registered”(ActiveMQ5.1)。
2. JDBC Master Slave(DB only)集群方式使用默认数据源进行测试时,频繁写入数据库,导致性能低下,MQ日志开始频繁报出“ERROR StoreDurableSubscriberCursor - Failed to get current cursor”的错误信息,JDBC Master Slave(File&DB)集群方式,使用默认数据源进行测试时,系统日志频繁报出“ERROR JournalPersistenceAdapter –Failed to checkpoint a message store: java.util.concurrent.ExecutionException: java.io.IOException: Already started. ”(更换了c3P0数据源后该问题可解决)。
3. Shared File System Master Slave在本次采用activeMQ5.1进行集群测试的时候也发现了一个BUG,在集群运行一段时候后会出现slave MQ的crash,日志显示为“java.io.FileNotFoundException: **/*****/***/******/journal/control.dat (Too many open files)”,在ActiveMQ的网站上找到了该BUG的错误报告。可通过升级到ACtiveMQ5.3或下载一个补丁jar包放到lib的方式来解决。
4. 目前开发提供的数据订阅模块在可持续订阅(duration)时处理效率较差,后续需要进行优化。
2.4 部署建议
参考文档:http://www.51testing.com/?uid-23978-action-viewspace-itemid-143163
1. Increase the memory limit of the broker in activemq.xml,在实际上线时需要评估消息发布、接送之间的msg流量差,增大memory limit,如512MB或更大,同时需要注意配置分配给ActiveMQ的JVM内存是大于该配置容量。
2. 建议以后对持续订阅模块进行性能评估后再上线部署,以防止消息订阅者性能低下而在ActiveMQ上造成数据堵塞;并保证持续订阅者的稳定性,避免出现长时间掉线的情况,测试证明消息堵塞对MQ性能的影响是很严重的。也可以通过配置消息生存时间、配置自动清除缓存等方式解决该隐患
3. 如果使用数据库模式的话建议使用c3p0的数据源。
4. 使用non-persistent 方式速度较快,对于偶尔丢失少量数据不敏感的应用极为适合。
至此,该阶段的集群性能评估已经可以告一段落,完整诊断以后系统性能的瓶颈主要是在持续订阅模块上。而采用c3po数据源后的JDBC Master Slave性能与Shared File System Master Slave 性能比较接近。Pure Master Slave的问题在apache网站上搜索据说该BUG已在ActiveMQ5.2后fixed,不过鉴于该集群方案的稳定性和以及故障后本身固有的处理缺陷暂不采用。
http://activemq.apache.org/masterslave.html
2. 服务器软件
apache-activemq-5.1.0
2.1 特性及优势
1、实现JMS1.1规范,支持J2EE1.4以上
2、可运行于任何jvm和大部分web容器(ActiveMQ works great in any JVM)
3、支持多种语言客户端(java, C, C++, AJAX, ACTIONSCRIPT等等)
4、支持多种协议(stomp,openwire,REST)
5、良好的spring支持(ActiveMQ has great Spring Support)
6、速度很快,JBossMQ的十倍(ActiveMQ is very fast; often 10x faster than JBossMQ.)
7、与OpenJMS、JbossMQ等开源jms provider相比,ActiveMQ有Apache的支持,持续发展的优势明显。
2.2 集群方式
在一个网络内运行多个brokers或者stand alone brokers时存在一个问题,这就是消息在物理上只被一个broker持有,因此当某个broker失效,那么你只能等待直到它重启后,这个broker上的消息才能够被继续发送(如果没有设置持久化,那么在这种情况下,消息将会丢失)。Master Slave 背后的想法是,消息被复制到slave broker,因此即使master broker遇到了像硬件故障之类的错误,你也可以立即切换到slave broker而不丢失任何消息。
Master Slave是目前ActiveMQ推荐的高可靠性和容错的解决方案。以下是几种不同的类型:
Master Slave Type
Requirements
Pros
Cons
Pure Master Slave
None
No central point of failure
Requires manual restart to bring back a failed master and can only support 1 slave
Shared File System Master Slave
A Shared File system such as a SAN
Run as many slaves as required. Automatic recovery of old masters
Requires shared file system
JDBC Master Slave
A Shared database
Run as many slaves as required. Automatic recovery of old masters
Requires a shared database. Also relatively slow as it cannot use the high performance journal
2.2.1 Pure Master Slave
Ø Pure Master Slave的工作方式如下:
Slave broker消费master broker上所有的消息状态,例如消息、确认和事务状态等。只要slave broker连接到了master broker,它不会(也不被允许)启动任何network connectors或者transport connectors,所以唯一的目的就是复制master broker的状态。
Master broker只有在消息成功被复制到slave broker之后才会响应客户。例如,客户的commit请求只有在master broker和slave broker都处理完毕commit请求之后才会结束。
当master broker失效的时候,slave broker有两种选择,一种是slave broker启动所有的network connectors和transport connectors,这允许客户端切换到slave broker;另外一种是slave broker停止。这种情况下,slave broker只是复制了master broker的状态。
客户应该使用failover transport并且应该首先尝试连接master broker。例如:
failover://(tcp://masterhost:61616,tcp://slavehost:61616)?randomize=false
设置randomize为false就可以让客户总是首先尝试连接master broker(slave broker并不会接受任何连接,直到它成为了master broker)。
Ø Pure Master Slave具有以下限制:
只能有一个slave broker连接到master broker。
在因master broker失效而导致slave broker成为master之后,之前的master broker只有在当前的master broker(原slave broker)停止后才能重新生效。
Master broker失效后而切换到slave broker后,最安全的恢复master broker的方式是人工处理。首先要停止slave broker(这意味着所有的客户也要停止)。然后把slave broker的数据目录中所有的数据拷贝到master broker的数据目录中。然后重启master broker和slave broker。
Ø Master broker不需要特殊的配置。Slave broker需要进行以下配置:
Xml代码:
<broker masterConnectorURI="tcp://masterhost:62001" shutdownOnMasterFailure="false">
...
<transportConnectors>
<transportConnector uri="tcp://slavehost:61616"/>
</transportConnectors>
</broker>
<broker masterConnectorURI="tcp://masterhost:62001" shutdownOnMasterFailure="false">
...
<transportConnectors>
<transportConnector uri="tcp://slavehost:61616"/>
</transportConnectors>
</broker>
其中的masterConnectorURI用于指向master broker,shutdownOnMasterFailure用于指定slave broker在master broker失效的时候是否需要停止。此外,也可以使用如下配置:
Xml代码 :
<broker brokerName="slave" useJmx="false" deleteAllMessagesOnStartup="true" xmlns="http://activemq.org/config/1.0">
...
<services>
<masterConnector remoteURI= "tcp://localhost:62001" userName="user" password="password"/>
</services>
</broker>
<broker brokerName="slave" useJmx="false" deleteAllMessagesOnStartup="true" xmlns="http://activemq.org/config/1.0">
...
<services>
<masterConnector remoteURI= "tcp://localhost:62001" userName="user" password="password"/>
</services>
</broker>
需要注意的是,笔者认为ActiveMQ5.0版本的Pure Master Slave仍然不够稳定。
客户端连接参数:failover://(tcp://masterhost:61616,tcp://slavehost:61616)?randomize=false
2.2.2 Shared File System Master Slave
如果你使用SAN(存储域网络(Storage Area Network))或者共享文件系统,那么你可以使用Shared File System Master Slave。基本上,你可以运行多个broker,这些broker共享数据目录。当第一个broker得到文件上的排他锁之后,其它的broker便会在循环中等待获得这把锁。客户端使用failover transport来连接到可用的broker。当master broker失效的时候会释放这把锁,这时候其中一个slave broker会得到这把锁从而成为master broker。以下是ActiveMQ配置的一个例子:
Xml代码 :
<broker useJmx="false" xmlns="http://activemq.org/config/1.0">
<persistenceAdapter>
<journaledJDBC dataDirectory="/sharedFileSystem/broker"/>
</persistenceAdapter>
…
</broker>
<broker useJmx="false" xmlns="http://activemq.org/config/1.0">
<persistenceAdapter>
<journaledJDBC dataDirectory="/sharedFileSystem/broker"/>
</persistenceAdapter>
…
</broker>
客户端连接参数:failover:(tcp://broker1:61616,tcp://broker2:61616,tcp://broker3:61616)
2.2.3 JDBC Master Slave
JDBC Master Slave的工作原理跟Shared File System Master Slave类似,只是采用了数据库作为持久化存储。以下是ActiveMQ配置的一个例子:
Xml代码 :
<beans>
<broker xmlns="http://activemq.org/config/1.0" brokerName="JdbcMasterBroker">
...
<persistenceAdapter>
<jdbcPersistenceAdapter dataSource="#mysql-ds"/>
</persistenceAdapter>
</broker>
<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:3306/test?relaxAutoCommit=true"/>
<property name="username" value="username"/>
<property name="password" value="passward"/>
<property name="poolPreparedStatements" value="true"/>
</bean>
</beans>
客户端连接参数:failover:(tcp://broker1:61616,tcp://broker2:61616,tcp://broker3:61616) <beans>
<broker xmlns="http://activemq.org/config/1.0" brokerName="JdbcMasterBroker">
...
<persistenceAdapter>
<jdbcPersistenceAdapter dataSource="#mysql-ds"/>
</persistenceAdapter>
</broker>
<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:3306/test?relaxAutoCommit=true"/>
<property name="username" value="username"/>
<property name="password" value="passward"/>
<property name="poolPreparedStatements" value="true"/>
</bean>
</beans>
2.3 测试结论
参考文档:http://www.51testing.com/?uid-23978-action-viewspace-itemid-143163
1. Pure Master Slaver集群方式重新启动MQ服务后原来连着的用户发送订阅消息,MQ会一直提示”Cannot lookup a connection that had not been registered”(ActiveMQ5.1)。
2. JDBC Master Slave(DB only)集群方式使用默认数据源进行测试时,频繁写入数据库,导致性能低下,MQ日志开始频繁报出“ERROR StoreDurableSubscriberCursor - Failed to get current cursor”的错误信息,JDBC Master Slave(File&DB)集群方式,使用默认数据源进行测试时,系统日志频繁报出“ERROR JournalPersistenceAdapter –Failed to checkpoint a message store: java.util.concurrent.ExecutionException: java.io.IOException: Already started. ”(更换了c3P0数据源后该问题可解决)。
3. Shared File System Master Slave在本次采用activeMQ5.1进行集群测试的时候也发现了一个BUG,在集群运行一段时候后会出现slave MQ的crash,日志显示为“java.io.FileNotFoundException: **/*****/***/******/journal/control.dat (Too many open files)”,在ActiveMQ的网站上找到了该BUG的错误报告。可通过升级到ACtiveMQ5.3或下载一个补丁jar包放到lib的方式来解决。
4. 目前开发提供的数据订阅模块在可持续订阅(duration)时处理效率较差,后续需要进行优化。
2.4 部署建议
参考文档:http://www.51testing.com/?uid-23978-action-viewspace-itemid-143163
1. Increase the memory limit of the broker in activemq.xml,在实际上线时需要评估消息发布、接送之间的msg流量差,增大memory limit,如512MB或更大,同时需要注意配置分配给ActiveMQ的JVM内存是大于该配置容量。
2. 建议以后对持续订阅模块进行性能评估后再上线部署,以防止消息订阅者性能低下而在ActiveMQ上造成数据堵塞;并保证持续订阅者的稳定性,避免出现长时间掉线的情况,测试证明消息堵塞对MQ性能的影响是很严重的。也可以通过配置消息生存时间、配置自动清除缓存等方式解决该隐患
3. 如果使用数据库模式的话建议使用c3p0的数据源。
4. 使用non-persistent 方式速度较快,对于偶尔丢失少量数据不敏感的应用极为适合。
至此,该阶段的集群性能评估已经可以告一段落,完整诊断以后系统性能的瓶颈主要是在持续订阅模块上。而采用c3po数据源后的JDBC Master Slave性能与Shared File System Master Slave 性能比较接近。Pure Master Slave的问题在apache网站上搜索据说该BUG已在ActiveMQ5.2后fixed,不过鉴于该集群方案的稳定性和以及故障后本身固有的处理缺陷暂不采用。