测试ActiveMQ主从复制

前天搭建了一个避免单点故障的基于zokeeper和leveldb的store。昨天测过了,kill掉Master,客户端确实是可以自动切换到被新推举出来的broker。但是消息是否也被复制过去了?会不会造成消息的丢失还需要测试一下。

测试流程

1.编写Sender和Receiver代码,通过客户端配置failover 进行一次正常的消息的发送和收,确保消息的传递是正常的。
2.通过Sender发送一段正常的消息到broker,但是不接受,然后kill 掉当前主broker,然后在运行Receiver代码,查看消息是否接受到。

步骤一

package com.shiquanjiumei.test;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class TestMQSender {
     private static final int SEND_NUMBER = 5;

        public static void main(String[] args) {
            // ConnectionFactory :连接工厂,JMS 用它创建连接
            ConnectionFactory connectionFactory;
            // Connection :JMS 客户端到JMS Provider 的连接
            Connection connection = null;
            // Session: 一个发送或接收消息的线程
            Session session;
            // Destination :消息的目的地;消息发送给谁.
            Destination destination;
            // MessageProducer:消息发送者
            MessageProducer producer;
            // TextMessage message;
            // 构造ConnectionFactory实例对象,此处采用ActiveMq的实现jar
            connectionFactory = new ActiveMQConnectionFactory(
                    ActiveMQConnection.DEFAULT_USER,
                    ActiveMQConnection.DEFAULT_PASSWORD,
                    "failover:(tcp://IP:61616,tcp://IP:61617,tcp://IP:61618)");
            try {
                // 构造从工厂得到连接对象
                connection = connectionFactory.createConnection();
                // 启动
                connection.start();
                // 获取操作连接
                session = connection.createSession(Boolean.TRUE,
                        Session.AUTO_ACKNOWLEDGE);
                // 获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置
                destination = session.createQueue("FirstQueue");
                // 得到消息生成者【发送者】
                producer = session.createProducer(destination);
                // 设置不持久化,此处学习,实际根据项目决定
                producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
                // 构造消息,此处写死,项目就是参数,或者方法获取
                sendMessage(session, producer);
                session.commit();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (null != connection)
                        connection.close();
                } catch (Throwable ignore) {
                }
            }
        }

        public static void sendMessage(Session session, MessageProducer producer)
                throws Exception {
//          for (int i = 1; i <= SEND_NUMBER; i++) {
                TextMessage message = session
                        .createTextMessage("ActiveMq 发送的消息:yivan" /*+ i*/);
                // 发送消息到目的地方
                System.out.println("发送消息:" + "ActiveMq 发送的消息:yivan" /*+ i*/);
                producer.send(message);
//          }
        }
}

接受端代码

package com.shiquanjiumei.test;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class TestMQReceiver {
     public static void main(String[] args) {
            // ConnectionFactory :连接工厂,JMS 用它创建连接
            ConnectionFactory connectionFactory;
            // Connection :JMS 客户端到JMS Provider 的连接
            Connection connection = null;
            // Session: 一个发送或接收消息的线程
            Session session;
            // Destination :消息的目的地;消息发送给谁.
            Destination destination;
            // 消费者,消息接收者
            MessageConsumer consumer;
            connectionFactory = new ActiveMQConnectionFactory(
                    ActiveMQConnection.DEFAULT_USER,
                    ActiveMQConnection.DEFAULT_PASSWORD,
                    "failover:(tcp://IP:61616,tcp://IP:61617,tcp://IP:61618)");
            try {
                // 构造从工厂得到连接对象
                connection = connectionFactory.createConnection();
                // 启动
                connection.start();
                // 获取操作连接
                session = connection.createSession(Boolean.FALSE,
                        Session.AUTO_ACKNOWLEDGE);
                // 获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置
                destination = session.createQueue("FirstQueue");
                consumer = session.createConsumer(destination);
                while (true) {
                    //设置接收者接收消息的时间,为了便于测试,这里谁定为100s
                    TextMessage message = (TextMessage) consumer.receive(100000);
                    if (null != message) {
                        System.out.println("收到消息" + message.getText());
                    } else {
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (null != connection)
                        connection.close();
                } catch (Throwable ignore) {
                }
            }
        }
}

步骤一比较简单,结果表明现阶段运行时正常的

发送消息:ActiveMq 发送的消息:yivan

步骤二

先运行Sender,向队列中发送消息,可以看到有一条待消费信息,但是没有消费者。
这里写图片描述

接下来,登录linux kill掉主Master,我现在的Master是61617.通过观察日志
在杀死主进程的一刹那是拒绝链接的,最后当61618被推出来当主的时候,又正常了。

DEBUG 2015-12-09 15:07:12,718 org.apache.activemq.util.ThreadPoolUtils: Forcing shutdown of ExecutorService: java.util.concurrent.ThreadPoolExecutor@288c2c89[Running, pool size = 1, active threads = 0, queued tasks = 0, completed tasks = 1]
DEBUG 2015-12-09 15:07:12,718 org.apache.activemq.transport.failover.FailoverTransport: Attempting  7th  connect to: tcp://127.0.0.1:61616
DEBUG 2015-12-09 15:07:12,719 org.apache.activemq.transport.failover.FailoverTransport: Connect fail to: tcp://127.0.0.1:61616, reason: java.net.ConnectException: 拒绝连接
DEBUG 2015-12-09 15:07:12,719 org.apache.activemq.transport.tcp.TcpTransport: Stopping transport tcp://127.0.0.1:61616
DEBUG 2015-12-09 15:07:12,719 org.apache.activemq.thread.TaskRunnerFactory: Initialized TaskRunnerFactory[ActiveMQ Task] using ExecutorService: java.util.concurrent.ThreadPoolExecutor@61501cb0[Running, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]
DEBUG 2015-12-09 15:07:12,722 org.apache.activemq.transport.tcp.TcpTransport$1: Closed socket Socket[unconnected]
DEBUG 2015-12-09 15:07:12,722 org.apache.activemq.util.ThreadPoolUtils: Forcing shutdown of ExecutorService: java.util.concurrent.ThreadPoolExecutor@61501cb0[Running, pool size = 1, active threads = 0, queued tasks = 0, completed tasks = 1]
DEBUG 2015-12-09 15:07:12,722 org.apache.activemq.transport.failover.FailoverTransport: Attempting  7th  connect to: tcp://127.0.0.1:61617
DEBUG 2015-12-09 15:07:12,723 org.apache.activemq.transport.failover.FailoverTransport: Connect fail to: tcp://127.0.0.1:61617, reason: java.net.ConnectException: 拒绝连接
DEBUG 2015-12-09 15:07:12,724 org.apache.activemq.transport.tcp.TcpTransport: Stopping transport tcp://127.0.0.1:61617
DEBUG 2015-12-09 15:07:12,724 org.apache.activemq.thread.TaskRunnerFactory: Initialized TaskRunnerFactory[ActiveMQ Task] using ExecutorService: java.util.concurrent.ThreadPoolExecutor@4a66875b[Running, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]
DEBUG 2015-12-09 15:07:12,724 org.apache.activemq.transport.tcp.TcpTransport$1: Closed socket Socket[unconnected]
DEBUG 2015-12-09 15:07:12,724 org.apache.activemq.util.ThreadPoolUtils: Forcing shutdown of ExecutorService: java.util.concurrent.ThreadPoolExecutor@4a66875b[Running, pool size = 1, active threads = 0, queued tasks = 0, completed tasks = 1]
DEBUG 2015-12-09 15:07:12,725 org.apache.activemq.transport.failover.FailoverTransport: Waiting 1280 ms before attempting connection
DEBUG 2015-12-09 15:07:14,006 org.apache.activemq.transport.failover.FailoverTransport: urlList connectionList:[tcp://127.0.0.1:61618, tcp://127.0.0.1:61616, tcp://127.0.0.1:61617], from: [tcp://127.0.0.1:61616, tcp://127.0.0.1:61617, tcp://127.0.0.1:61618]
DEBUG 2015-12-09 15:07:14,006 org.apache.activemq.transport.failover.FailoverTransport: Waiting 2560 ms before attempting connection. 
DEBUG 2015-12-09 15:07:16,196 org.springframework.web.servlet.DispatcherServlet: DispatcherServlet with name 'front' processing POST request for [/clouds/customer/getcustomerdata.shtml]
DEBUG 2015-12-09 15:07:16,196 org.springframework.web.servlet.handler.AbstractUrlHandlerMapping: Mapping [/customer/getcustomerdata.shtml] to HandlerExecutionChain with handler [com.shiquanjiumei.controller.interfaces.CustomerDataController@58c8b978] and 1 interceptor
DEBUG 2015-12-09 15:07:16,197 org.springframework.web.bind.annotation.support.HandlerMethodInvoker: Invoking request handler method: public void com.shiquanjiumei.controller.interfaces.CustomerDataController.getCustomerMessage(java.lang.String,java.lang.String,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws java.net.UnknownHostException
DEBUG 2015-12-09 15:07:16,197 org.springframework.beans.factory.support.AbstractBeanFactory: Returning cached instance of singleton bean 'transactionManager'
DEBUG 2015-12-09 15:07:16,197 org.springframework.transaction.support.AbstractPlatformTransactionManager: Creating new transaction with name [com.shiquanjiumei.service.impl.BaseSetingServiceImpl.getCustomerMessage]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
DEBUG 2015-12-09 15:07:16,197 com.mchange.v2.resourcepool.BasicResourcePool: trace com.mchange.v2.resourcepool.BasicResourcePool@1db6ed76 [managed: 6, unused: 5, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@20f78840)
DEBUG 2015-12-09 15:07:16,197 org.springframework.jdbc.datasource.DataSourceTransactionManager: Acquired Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@1fc9a6ad] for JDBC transaction
DEBUG 2015-12-09 15:07:16,197 org.springframework.jdbc.datasource.DataSourceTransactionManager: Switching JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@1fc9a6ad] to manual commit
DEBUG 2015-12-09 15:07:16,198 org.mybatis.spring.SqlSessionUtils: Creating a new SqlSession
DEBUG 2015-12-09 15:07:16,198 org.mybatis.spring.SqlSessionUtils: Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6fddb828]
DEBUG 2015-12-09 15:07:16,198 org.mybatis.spring.transaction.SpringManagedTransaction: JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@1fc9a6ad] will be managed by Spring
DEBUG 2015-12-09 15:07:16,199 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==>  Preparing: select * from t_customer where registerTime between ? and ? 
DEBUG 2015-12-09 15:07:16,199 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: 2015-12-09 03:07:30(String), 2015-12-09 03:07:40(String)
DEBUG 2015-12-09 15:07:16,200 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <==      Total: 0
DEBUG 2015-12-09 15:07:16,200 org.mybatis.spring.SqlSessionUtils: Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6fddb828]
DEBUG 2015-12-09 15:07:16,200 org.mybatis.spring.SqlSessionUtils$SqlSessionSynchronization: Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6fddb828]
DEBUG 2015-12-09 15:07:16,200 org.mybatis.spring.SqlSessionUtils$SqlSessionSynchronization: Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6fddb828]
DEBUG 2015-12-09 15:07:16,200 org.mybatis.spring.SqlSessionUtils$SqlSessionSynchronization: Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6fddb828]
DEBUG 2015-12-09 15:07:16,200 org.springframework.transaction.support.AbstractPlatformTransactionManager: Initiating transaction commit
DEBUG 2015-12-09 15:07:16,200 org.springframework.jdbc.datasource.DataSourceTransactionManager: Committing JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@1fc9a6ad]
DEBUG 2015-12-09 15:07:16,201 org.springframework.jdbc.datasource.DataSourceTransactionManager: Releasing JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@1fc9a6ad] after transaction
DEBUG 2015-12-09 15:07:16,201 org.springframework.jdbc.datasource.DataSourceUtils: Returning JDBC Connection to DataSource
DEBUG 2015-12-09 15:07:16,201 com.mchange.v2.resourcepool.BasicResourcePool: trace com.mchange.v2.resourcepool.BasicResourcePool@1db6ed76 [managed: 6, unused: 5, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@20f78840)
DEBUG 2015-12-09 15:07:16,201 org.springframework.web.servlet.DispatcherServlet: Null ModelAndView returned to DispatcherServlet with name 'front': assuming HandlerAdapter completed request handling
DEBUG 2015-12-09 15:07:16,202 org.springframework.web.servlet.FrameworkServlet: Successfully completed request
DEBUG 2015-12-09 15:07:16,566 org.apache.activemq.transport.failover.FailoverTransport: Attempting  8th  connect to: tcp://127.0.0.1:61618

但是当我查看后台或者运行接受Receiveder代码的时候,原来的消息丢失了。这怎么可以,这还怎么玩。
这里写图片描述

其实问题在Sender的代码中
将NON_PERSISTENT 改为PERSISTENT

  // 设置不持久化,实际根据项目决定
  producer.setDeliveryMode(DeliveryMode.PERSISTENT);

在运行一遍测试流程2,发现及时当时收到消息的是server1 ,你讲server1 kill 掉后,用Recevieder的代码从新的broker中接受依旧能接受到,原因就是他进行了LevelDB本地存贮,这种文件系统是从ActiveMQ5.8之后引进的,它和KahaDB非常相似,也是基于文件的本地数据库储存形式,但是它提供比KahaDB更快的持久性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值