activeMQ 接收、销毁删除数据条数不一致

1.      问题描述:

a.      服务端发送500条记录,如果立马启动客户端,客户端接收200条,卡顿之后显示接收数据为200条或者超过200条,而服务端只从队列删除了200条。

b.      如果等待片刻,再启动客户端,可全部接收。

c.      如果在客户端session.commit()之前等待若干长时间,也可全部接收。

2.     可能原因: MQ默认MaxPageSize(maximum number of persistent messages to pagefrom store at a time)为200,分析可能原因是服务端需要时间建立一个page,这个page装满后再建一个page,这些都需要时间;客户端接收太快,很快将200条接收完,而服务器端未来得及建立完下个page,所以客户端以为全部接收完,开始commit,导致服务端只销毁200条记录。

3.     如何解决:适当加大page容量

<policyEntryqueue=">"producerFlowControl="true"memoryLimit="2mb"maxPageSize="1000"/>


参考程序:点对点PTP模式

服务端:

package cn.ac.iscas.zdy.p2p;


import javax.jms.DeliveryMode;
import javax.jms.MapMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSession;
import javax.jms.Session;


import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;


public class QueueSender {

private static final int SEND_NUM = 1500;
    private static final String BROKER_URL = "tcp://localhost:61616";
    private static final String DESTINATION = "hoo.mq.queue";
    
    public static void sendMessage(QueueSession session, javax.jms.QueueSender sender) throws Exception {
        for (int i = 0; i < SEND_NUM; i++) {
            String message = "发送消息第" + (i + 1) + "条";
            MapMessage map = session.createMapMessage();
            map.setString("text", message);
            map.setLong("time", System.currentTimeMillis());
            System.out.println(map);
            
            sender.send(map);
            //Thread.sleep(1000);
        }
    }
    
    public static void run() throws Exception {
        
        QueueConnection connection = null;
        QueueSession session = null;
        try {
            QueueConnectionFactory factory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, BROKER_URL);
            connection = factory.createQueueConnection();
            connection.start();
            session = connection.createQueueSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
            Queue queue = session.createQueue(DESTINATION);
            javax.jms.QueueSender sender = session.createSender(queue);
            sender.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
            
            sendMessage(session, sender);
            session.commit();
            
            
            
        } catch (Exception e) {
            throw e;
        } finally {
            if (session != null) {
                session.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
    }
    
    public static void main(String[] args) throws Exception {
        QueueSender.run();
    }
}


客户端:

package cn.ac.iscas.zdy.p2p;

import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSession;
import javax.jms.Session;


import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;


public class QueueReceiver {


private static final String BROKER_URL = "tcp://localhost:61616";
    private static final String TARGET = "hoo.mq.queue?customer.prefetchSize=400";
    
    public static void run() throws Exception {
        
        QueueConnection connection = null;
        QueueSession session = null;
        try {
            QueueConnectionFactory factory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,ActiveMQConnection.DEFAULT_PASSWORD,BROKER_URL);
            connection = factory.createQueueConnection();
            ((ActiveMQConnection)connection).setUseAsyncSend(true);
            connection.start();
            session = connection.createQueueSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
            Queue queue = session.createQueue(TARGET);
            javax.jms.QueueReceiver receiver = session.createReceiver(queue);
            
            receiver.setMessageListener(new MessageListener() { 
                public void onMessage(Message msg) { 
                    if (msg != null) {
                        MapMessage map = (MapMessage) msg;
                        try {
                            System.out.println(map.getLong("time") + "接收#" + map.getString("text"));
                        } catch (JMSException e) {
                            e.printStackTrace();
                        }
                        
                    }
                } 
            }); 
            
            
            Thread.sleep(1000*10); 
            
            session.commit();
            
        } catch (Exception e) {
            throw e;
        } finally {
            if (session != null) {
                session.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
    }
    
    public static void main(String[] args) throws Exception {
        QueueReceiver.run();
    }  
}

展开阅读全文

没有更多推荐了,返回首页