ActiveMQ消费者详解

阅读更多
JMS(ActiveMQ) PTP和PUB/SUB模式实例: http://donald-draper.iteye.com/blog/2347445
ActiveMQ连接工厂、连接详解: http://donald-draper.iteye.com/blog/2348070
ActiveMQ会话初始化: http://donald-draper.iteye.com/blog/2348341
ActiveMQ生产者: http://donald-draper.iteye.com/blog/2348381
ActiveMQ消费者: http://donald-draper.iteye.com/blog/2348389
ActiveMQ启动过程详解 :http://donald-draper.iteye.com/blog/2348399
ActiveMQ Broker发送消息给消费者过程详解: http://donald-draper.iteye.com/blog/2348440
Spring与ActiveMQ的集成: http://donald-draper.iteye.com/blog/2347638
Spring与ActiveMQ的集成详解一: http://donald-draper.iteye.com/blog/2348449
Spring与ActiveMQ的集成详解二: http://donald-draper.iteye.com/blog/2348461
上一篇我们讲了生产者,今天来说一下消费者,从下面这段开始
// Destination :消息的目的地;消息发送给谁.  
Topic destination=session.createTopic(tname);  
// 消费者,消息接收者  
MessageConsumer consumer = session.createConsumer(destination);  


//ActiveMQSession创建消费者
public MessageConsumer createConsumer(Destination destination)
        throws JMSException
    {
        return createConsumer(destination, (String)null);
    }

    public MessageConsumer createConsumer(Destination destination, String messageSelector)
        throws JMSException
    {
        return createConsumer(destination, messageSelector, false);
    }

    public MessageConsumer createConsumer(Destination destination, MessageListener messageListener)
        throws JMSException
    {
        return createConsumer(destination, null, messageListener);
    }

    public MessageConsumer createConsumer(Destination destination, String messageSelector, MessageListener messageListener)
        throws JMSException
    {
        return createConsumer(destination, messageSelector, false, messageListener);
    }

    public MessageConsumer createConsumer(Destination destination, String messageSelector, boolean noLocal)
        throws JMSException
    {
        return createConsumer(destination, messageSelector, noLocal, null);
    }

    public MessageConsumer createConsumer(Destination destination, String messageSelector, boolean noLocal, MessageListener messageListener)
        throws JMSException
    {
        checkClosed();
        if(destination instanceof CustomDestination)
        {
            CustomDestination customDestination = (CustomDestination)destination;
            return customDestination.createConsumer(this, messageSelector, noLocal);
        }
	//从连接后去获取消息策略
        ActiveMQPrefetchPolicy prefetchPolicy = connection.getPrefetchPolicy();
        int prefetch = 0;
        if(destination instanceof Topic)
            prefetch = prefetchPolicy.getTopicPrefetch();
        else
            prefetch = prefetchPolicy.getQueuePrefetch();
        ActiveMQDestination activemqDestination = ActiveMQMessageTransformation.transformDestination(destination);
        //创建消费者
	return new ActiveMQMessageConsumer(this, getNextConsumerId(), activemqDestination, null, messageSelector, prefetch, prefetchPolicy.getMaximumPendingMessageLimit(), noLocal, false, isAsyncDispatch(), messageListener);
    }



public class ActiveMQMessageConsumer
    implements MessageAvailableConsumer, StatsCapable, ActiveMQDispatcher
{
   protected final ActiveMQSession session;
    protected final ConsumerInfo info;//消费者信息
    protected final MessageDispatchChannel unconsumedMessages;//消息分发通道(没消费的消息)
    protected final LinkedList deliveredMessages = new LinkedList();//传输消息队列
    private PreviouslyDeliveredMap previouslyDeliveredMessages;
    private int deliveredCounter;//传输消息计数器
    private int additionalWindowSize;
    private long redeliveryDelay;//消息传输延时
    private int ackCounter;//消息回复计时器
    private int dispatchedCount;//消息分发计时器
    private final AtomicReference messageListener = new AtomicReference();//消息监听器引用
    private final JMSConsumerStatsImpl stats;//消费者状态信息管理器
    private final String selector;选择器
    private boolean synchronizationRegistered;
    private final AtomicBoolean started = new AtomicBoolean(false);//启动状态
    private MessageAvailableListener availableListener;
    private RedeliveryPolicy redeliveryPolicy;//传输策略
    private boolean optimizeAcknowledge;
    private final AtomicBoolean deliveryingAcknowledgements = new AtomicBoolean();
    private ExecutorService executorService;//执行器
    private MessageTransformer transformer;
    private boolean clearDeliveredList;
    AtomicInteger inProgressClearRequiredFlag;
    private MessageAck pendingAck;//消息回复
    private long lastDeliveredSequenceId;
    private IOException failureError;
    private long optimizeAckTimestamp;
    private long optimizeAcknowledgeTimeOut;
    private long optimizedAckScheduledAckInterval;
    private Runnable optimizedAckTask;//消息回复优化任务
    private long failoverRedeliveryWaitPeriod;//当Master宕机时,消息传输等待时间
    private boolean transactedIndividualAck;
    private boolean nonBlockingRedelivery;//是否非阻塞传输
    private boolean consumerExpiryCheckEnabled;
     public ActiveMQMessageConsumer(ActiveMQSession session, ConsumerId consumerId, ActiveMQDestination dest, String name, String selector, int prefetch, int maximumPendingMessageCount, 
            boolean noLocal, boolean browser, boolean dispatchAsync, MessageListener messageListener)
        throws JMSException
    {
        inProgressClearRequiredFlag = new AtomicInteger(0);
        lastDeliveredSequenceId = -1L;
        optimizeAckTimestamp = System.currentTimeMillis();
        optimizeAcknowledgeTimeOut = 0L;
        optimizedAckScheduledAckInterval = 0L;
        failoverRedeliveryWaitPeriod = 0L;
        transactedIndividualAck = false;
        nonBlockingRedelivery = false;
        consumerExpiryCheckEnabled = true;
        if(dest == null)
            throw new InvalidDestinationException("Don't understand null destinations");
        if(dest.getPhysicalName() == null)
            throw new InvalidDestinationException("The destination object was not given a physical name.");
        if(dest.isTemporary())
        {
            String physicalName = dest.getPhysicalName();
            if(physicalName == null)
                throw new IllegalArgumentException((new StringBuilder()).append("Physical name of Destination should be valid: ").append(dest).toString());
            String connectionID = session.connection.getConnectionInfo().getConnectionId().getValue();
            if(physicalName.indexOf(connectionID) < 0)
                throw new InvalidDestinationException("Cannot use a Temporary destination from another Connection");
            if(session.connection.isDeleted(dest))
                throw new InvalidDestinationException("Cannot use a Temporary destination that has been deleted");
            if(prefetch < 0)
                throw new JMSException("Cannot have a prefetch size less than zero");
        }
	//配置消息分发通道
        if(session.connection.isMessagePrioritySupported())
            unconsumedMessages = new SimplePriorityMessageDispatchChannel();
        else
            unconsumedMessages = new FifoMessageDispatchChannel();
        this.session = session;
	//获取连接重新传输策略
        redeliveryPolicy = session.connection.getRedeliveryPolicyMap().getEntryFor(dest);
        setTransformer(session.getTransformer());
        info = new ConsumerInfo(consumerId);
        info.setExclusive(this.session.connection.isExclusiveConsumer());
        info.setClientId(this.session.connection.getClientID());
        info.setSubscriptionName(name);
        info.setPrefetchSize(prefetch);
        info.setCurrentPrefetchSize(prefetch);
        info.setMaximumPendingMessageLimit(maximumPendingMessageCount);
        info.setNoLocal(noLocal);
        info.setDispatchAsync(dispatchAsync);
        info.setRetroactive(this.session.connection.isUseRetroactiveConsumer());
        info.setSelector(null);
        if(dest.getOptions() != null)
        {
            Map options = IntrospectionSupport.extractProperties(new HashMap(dest.getOptions()), "consumer.");
            IntrospectionSupport.setProperties(info, options);
            if(options.size() > 0)
            {
                String msg = (new StringBuilder()).append("There are ").append(options.size()).append(" consumer options that couldn't be set on the consumer.").append(" Check the options are spelled correctly.").append(" Unknown parameters=[").append(options).append("].").append(" This consumer cannot be started.").toString();
                LOG.warn(msg);
                throw new ConfigurationException(msg);
            }
        }
        info.setDestination(dest);
        info.setBrowser(browser);
        if(selector != null && selector.trim().length() != 0)
        {
            SelectorParser.parse(selector);
            info.setSelector(selector);
            this.selector = selector;
        } else
        if(info.getSelector() != null)
        {
            SelectorParser.parse(info.getSelector());
            this.selector = info.getSelector();
        } else
        {
            this.selector = null;
        }
	//创建消费者状态管理器
        stats = new JMSConsumerStatsImpl(session.getSessionStats(), dest);
        optimizeAcknowledge = session.connection.isOptimizeAcknowledge() && session.isAutoAcknowledge() && !info.isBrowser();
        if(optimizeAcknowledge)
        {
            optimizeAcknowledgeTimeOut = session.connection.getOptimizeAcknowledgeTimeOut();
            setOptimizedAckScheduledAckInterval(session.connection.getOptimizedAckScheduledAckInterval());
        }
        info.setOptimizedAcknowledge(optimizeAcknowledge);
        failoverRedeliveryWaitPeriod = session.connection.getConsumerFailoverRedeliveryWaitPeriod();
        nonBlockingRedelivery = session.connection.isNonBlockingRedelivery();
        transactedIndividualAck = session.connection.isTransactedIndividualAck() || nonBlockingRedelivery || session.connection.isMessagePrioritySupported();
        consumerExpiryCheckEnabled = session.connection.isConsumerExpiryCheckEnabled();
        if(messageListener != null)
	    //设置消息监听器
            setMessageListener(messageListener);
        try
        {
	    //将消费者添加到会话
            this.session.addConsumer(this);
	    //发送消费者信息给broker
            this.session.syncSendPacket(info);
        }
        catch(JMSException e)
        {
            this.session.removeConsumer(this);
            throw e;
        }
	//如果连接启动,则启动消费者
        if(session.connection.isStarted())
            start();
    }
}

创建消费者就是初始化消费者,传输延时,选择器,消息监听器,消息重传策略,并把消费者信息发送给broker,同时将消费者添加到会话中,启动会话执行器,通知消息者消费消息;


这个我们在会话启动篇又说,这里我们简单地说一下:

//启动消费者
   public void start()
        throws JMSException
    {
        if(unconsumedMessages.isClosed())
        {
            return;
        } else
        {
            started.set(true);
	    //启动消息通道,通知消息通道可以发送未消费的消息给消息者
            unconsumedMessages.start();
	    //通过会话执行器唤醒消费者,消费消息
            session.executor.wakeup();
            return;
        }
}


unconsumedMessages我们以先进先出消息分发通道来讲FifoMessageDispatchChannel
,还有一种是基于消息优先级的这里就不说了前文以说
public class FifoMessageDispatchChannel
    implements MessageDispatchChannel
{
    private final Object mutex = new Object();
    private final LinkedList list = new LinkedList();
    private boolean closed;
    private boolean running;
 public void start()
    {
        synchronized(mutex)
        {
	    //通知所有等待分发消息互斥量的线程
            running = true;
            mutex.notifyAll();
        }
    }
}

//唤醒会话执行器
session.executor.wakeup();

下面是我们前文的关于这一句的总结

稍微简单过一下
public class ActiveMQSessionExecutor
    implements Task
{
//唤醒消费者,消费消息
 public void wakeup()
    {
        //this为ActiveMQSessionExecutor,
        this.taskRunner = session.connection.getSessionTaskRunner().createTaskRunner(this, (new StringBuilder()).append("ActiveMQ Session: ").append(session.getSessionId()).toString());
        taskRunner = this.taskRunner;
	//唤醒任务线程,taskRunner实际为PooledTaskRunner
        taskRunner.wakeup();
    }
}


class PooledTaskRunner
    implements TaskRunner
{

    public PooledTaskRunner(Executor executor, final Task task, int maxIterationsPerRun)
    {
        this.executor = executor;
        this.maxIterationsPerRun = maxIterationsPerRun;
        this.task = task;
        runable = new Runnable() {

            public void run()
            {
                runningThread = Thread.currentThread();
		//运行任务
                runTask();
            }

            final Task val$task;
            final PooledTaskRunner this$0;

            
            {
                this$0 = PooledTaskRunner.this;
                task = task1;
                super();
            }
        };
    }     
}

final void runTask()
    {
label0:
        {
            synchronized(runable)
            {
                queued = false;
                if(!shutdown)
                    break label0;
                iterating = false;
                runable.notifyAll();
            }
            return;
        }
        iterating = true;
_L1:
        boolean done = false;
        int i = 0;
        do
        {
            if(i >= maxIterationsPerRun)
                break;
            LOG.trace("Running task iteration {} - {}", Integer.valueOf(i), task);
	    //关键在这一句,task为ActiveMQSessionExecutor
            if(!task.iterate())
            {
                done = true;
                break;
            }
            i++;
        } while(true);
        ...
    }



再看ActiveMQSessionExecutor
//ActiveMQSessionExecutor
 public boolean iterate()
    {
        for(Iterator i$ = session.consumers.iterator(); i$.hasNext();)
        {
            ActiveMQMessageConsumer consumer = (ActiveMQMessageConsumer)i$.next();
	    //遍历消费者,消费消息
            if(consumer.iterate())
                return true;
        }
        MessageDispatch message = messageQueue.dequeueNoWait();
        if(message == null)
        {
            return false;
        } else
        {
	    //分发为消费的消息
            dispatch(message);
            return !messageQueue.isEmpty();
        }
    }


我们来看这部分
ActiveMQMessageConsumer consumer = (ActiveMQMessageConsumer)i$.next();

//遍历消费者,消费消息
if(consumer.iterate())
return true;
//ActiveMQMessageConsumer
public boolean iterate()
    {
        MessageListener listener = (MessageListener)messageListener.get();
        if(listener != null)
        {
	    //从未消费消息通道,获取未消费消息
            MessageDispatch md = unconsumedMessages.dequeueNoWait();
            if(md != null)
            {
	         //如果有未消费的消息,则分发消息
                dispatch(md);
                return true;
            }
        }
        return false;
    }

//分发消息
 public void dispatch(MessageDispatch md)
    {
        ActiveMQMessage message = createActiveMQMessage(md);
        beforeMessageIsConsumed(md);
        try
        {
            boolean expired = isConsumerExpiryCheckEnabled() && message.isExpired();
            if(!expired)
	        //关键在这一句调用监听器的消费消息方法onMessage
                listener.onMessage(message);
            afterMessageIsConsumed(md, expired);
        }
    }

//从未消费消息通道,获取未消费消息
MessageDispatch md = unconsumedMessages.dequeueNoWait();
以先进先出消息通道为例FifoMessageDispatchChannel
//FifoMessageDispatchChannel
public class FifoMessageDispatchChannel
    implements MessageDispatchChannel
{
    private final Object mutex = new Object();
    private final LinkedList list = new LinkedList();//未分发消息队列
    private boolean closed;
    private boolean running;
   public MessageDispatch dequeueNoWait()
    {
        Object obj = mutex;
        JVM INSTR monitorenter ;
        if(closed || !running || list.isEmpty())
            return null;
	 //从消息队列获取队列头消息
        (MessageDispatch)list.removeFirst();
        obj;
        JVM INSTR monitorexit ;
        return;
        Exception exception;
        exception;
        throw exception;
    }
}

小节:
消费者启动主要是唤醒ActiveMQSessionExecutor,会话执行器唤醒主要做的做工作是
ActiveMQConnection创建任务执行TaskRunnerFactory,有任务执行工厂TaskRunnerFactory,有任务执行工厂创建执行任务PooledTaskRunner,PooledTaskRunner是ActiveMQSessionExecutor的包装,PooledTaskRunner执行就是执行ActiveMQSessionExecutor
iterate的函数,这个过程主要是ActiveMQSessionExecutor从ActiveMQSession获取会话消费者consumer,从未分发消息队列获取消息,然后遍历消费者,消费者通过MessageListener消费消息。


回到PooledTaskRunner
//唤醒会话执行器,执行PooledTaskRunner,分发未消费的消息给消费者
 public void wakeup()
        throws InterruptedException
    {
        {
            synchronized(runable)
            {
                if(!queued && !shutdown)
                    break label0;
            }
            return;
        }
        queued = true;
	//执行PooledTaskRunner
        if(!iterating)
            executor.execute(runable);
}





下面来看消费者消费的两种方式

消费消息两种方式
第一种消费消息方式:
while (true) { 
             //设置接收者接收消息的时间,为了便于测试,这里谁定为100s 
             TextMessage message = (TextMessage) consumer.receive(100000); 
             if (null != message) { 
                 System.out.println("收到消息" + message.getText()); 
             } else { 
                 break; 
             } 
         }*/  
   }  


public javax.jms.Message receive(long timeout)
        throws JMSException
    {
        checkClosed();
        checkMessageListener();
        if(timeout == 0L)
            return receive();
        sendPullCommand(timeout);
        if(timeout > 0L)
        {
            MessageDispatch md;
            if(info.getPrefetchSize() == 0)
                md = dequeue(-1L);
            else 
	        //获取消息
                md = dequeue(timeout);
            if(md == null)
            {
                return null;
            } else
            {
                beforeMessageIsConsumed(md);
                afterMessageIsConsumed(md, false);
		//包装消息
                return createActiveMQMessage(md);
            }
        } else
        {
            return null;
        }
    }



//获取消息
md = dequeue(timeout);


  private MessageDispatch dequeue(long timeout)
        throws JMSException
    {
        long deadline;
        deadline = 0L;
        if(timeout > 0L)
            deadline = System.currentTimeMillis() + timeout;
	//从未消费消息通道获取消息
        MessageDispatch md = unconsumedMessages.dequeue(timeout);
}

//包装消息
return createActiveMQMessage(md);
 private ActiveMQMessage createActiveMQMessage(final MessageDispatch md)
        throws JMSException
    {
        //获取消息类型
        ActiveMQMessage m = (ActiveMQMessage)md.getMessage().copy();
        if(m.getDataStructureType() == 29)
            ((ActiveMQBlobMessage)m).setBlobDownloader(new BlobDownloader(session.getBlobTransferPolicy()));
        if(transformer != null)
        {
	    //转换消息
            javax.jms.Message transformedMessage = transformer.consumerTransform(session, this, m);
            if(transformedMessage != null)
                m = ActiveMQMessageTransformation.transformMessage(transformedMessage, session.connection);
        }
        if(session.isClientAcknowledge())
            m.setAcknowledgeCallback(new Callback() {

                public void execute()
                    throws Exception
                {
                    session.checkClosed();
		    //如消息需要消费者回复,则产生回复消息
                    session.acknowledge();
                }

                final ActiveMQMessageConsumer this$0;

            
            {
                this$0 = ActiveMQMessageConsumer.this;
                super();
            }
            });
        else
        if(session.isIndividualAcknowledge())
            m.setAcknowledgeCallback(new Callback() {

                public void execute()
                    throws Exception
                {
                    session.checkClosed();
                    acknowledge(md);
                }

                final MessageDispatch val$md;
                final ActiveMQMessageConsumer this$0;

            
            {
                this$0 = ActiveMQMessageConsumer.this;
                md = messagedispatch;
                super();
            }
            });
        return m;
    }

从消费者直接消费消息来看,消费首先从未消费消息通道(FIFO,Priority)获取消息,然后转换消息。
第二种消费消息方式:
       consumer.setMessageListener(new MessageListener(){//有事务限制  
           @Override  
           public void onMessage(Message message) {  
               try {  
            	   ObjectMessage objMessage=(ObjectMessage)message;  
                   Order order = (Order)objMessage.getObject();
                   System.out.println("消费订单信息:"+order.toString()); 
                   
               } catch (JMSException e1) {  
                   e1.printStackTrace();  
               }  
               try {  
                   session.commit();  
               } catch (JMSException e) {  
                   e.printStackTrace();  
               }  
           }  
       });  



设置消息监听器
public void setMessageListener(MessageListener listener)
        throws JMSException
    {
        checkClosed();
        if(info.getPrefetchSize() == 0)
            throw new JMSException("Illegal prefetch size of zero. This setting is not supported for asynchronous consumers please set a value of at least 1");
        if(listener != null)
        {
            boolean wasRunning = session.isRunning();
            if(wasRunning)
                session.stop();
            //设置消费者消息监听器
            messageListener.set(listener);
	    //会话重新分发未消费消息
            session.redispatch(this, unconsumedMessages);
            if(wasRunning)
                session.start();
        } else
        {
            messageListener.set(null);
        }
    }


//会话重新分发未消费消息
session.redispatch(this, unconsumedMessages);


//ActiveMQSession
 public void redispatch(ActiveMQDispatcher dispatcher, MessageDispatchChannel unconsumedMessages)
        throws JMSException
    {
        List c = unconsumedMessages.removeAll();
        MessageDispatch md;
        for(Iterator i$ = c.iterator(); i$.hasNext(); connection.rollbackDuplicate(dispatcher, md.getMessage()))
            md = (MessageDispatch)i$.next();

        Collections.reverse(c);
        MessageDispatch md;
	//遍历为未消费消息,会话执行器通知消息者消费消息
        for(Iterator iter = c.iterator(); iter.hasNext(); executor.executeFirst(md))
            md = (MessageDispatch)iter.next();

    }


public class ActiveMQSessionExecutor
void executeFirst(MessageDispatch message)
    {
        //将未消费消息放入消息队列,待消费者消费
        messageQueue.enqueueFirst(message);
	//这个前面看到,唤醒消费者消费消息
        wakeup();
    }

监听器方式实际为会话从未消费消息队列获取消息,添加到消息队列,通过会话执行器通知消费者消费


总结:
创建消费者就是初始化消费者,传输延时,选择器,消息监听器,消息重传策略,并把消费者信息发送给broker,同时将消费者添加到会话中,启动会话执行器,通知消息者消费消息;消费者启动主要是唤醒ActiveMQSessionExecutor,会话执行器唤醒主要做的做工作是
ActiveMQConnection创建任务执行TaskRunnerFactory,有任务执行工厂TaskRunnerFactory,有任务执行工厂创建执行任务PooledTaskRunner,PooledTaskRunner是ActiveMQSessionExecutor的包装,PooledTaskRunner执行就是执行ActiveMQSessionExecutor
iterate的函数,这个过程主要是ActiveMQSessionExecutor从ActiveMQSession获取会话消费者consumer,从未分发消息队列获取消息,然后遍历消费者,消费者通过MessageListener消费消息。消费者直接消费消息方式为,消费首先从未消费消息通道(FIFO,Priority)获取消息,然后转换消息;监听器方式,实际为会话从未消费消息队列获取消息,添加到消息队列,通过会话执行器通知消费者消费。


public class MessageDispatch extends BaseCommand
{
    public static final byte DATA_STRUCTURE_TYPE = 21;
    protected ConsumerId consumerId;//消费者id
    protected ActiveMQDestination destination;//消息目的地
    protected Message message;//消息
    protected int redeliveryCounter;//重传计数器
    protected transient long deliverySequenceId;
    protected transient Object consumer;//消费者
    protected transient TransmitCallback transmitCallback;
    protected transient Throwable rollbackCause;

    public MessageDispatch()
    {
    }

    public byte getDataStructureType()
    {
        return 21;
    }

    public boolean isMessageDispatch()
    {
        return true;
    }

    public ConsumerId getConsumerId()
    {
        return consumerId;
    }

    public void setConsumerId(ConsumerId consumerId)
    {
        this.consumerId = consumerId;
    }

    public ActiveMQDestination getDestination()
    {
        return destination;
    }

    public void setDestination(ActiveMQDestination destination)
    {
        this.destination = destination;
    }

    public Message getMessage()
    {
        return message;
    }

    public void setMessage(Message message)
    {
        this.message = message;
    }

    public long getDeliverySequenceId()
    {
        return deliverySequenceId;
    }

    public void setDeliverySequenceId(long deliverySequenceId)
    {
        this.deliverySequenceId = deliverySequenceId;
    }

    public int getRedeliveryCounter()
    {
        return redeliveryCounter;
    }

    public void setRedeliveryCounter(int deliveryCounter)
    {
        redeliveryCounter = deliveryCounter;
    }

    public Object getConsumer()
    {
        return consumer;
    }

    public void setConsumer(Object consumer)
    {
        this.consumer = consumer;
    }

    public Response visit(CommandVisitor visitor)
        throws Exception
    {
        return visitor.processMessageDispatch(this);
    }

    public TransmitCallback getTransmitCallback()
    {
        return transmitCallback;
    }

    public void setTransmitCallback(TransmitCallback transmitCallback)
    {
        this.transmitCallback = transmitCallback;
    }

    public Throwable getRollbackCause()
    {
        return rollbackCause;
    }

    public void setRollbackCause(Throwable rollbackCause)
    {
        this.rollbackCause = rollbackCause;
    }

}


//消息获取策略
public class ActiveMQPrefetchPolicy
    implements Serializable
{
    public static final int MAX_PREFETCH_SIZE = 32767;
    public static final int DEFAULT_QUEUE_PREFETCH = 1000;
    public static final int DEFAULT_QUEUE_BROWSER_PREFETCH = 500;
    public static final int DEFAULT_DURABLE_TOPIC_PREFETCH = 100;
    public static final int DEFAULT_OPTIMIZE_DURABLE_TOPIC_PREFETCH = 1000;
    public static final int DEFAULT_TOPIC_PREFETCH = 32767;
    private static final Logger LOG = LoggerFactory.getLogger(org/apache/activemq/ActiveMQPrefetchPolicy);
    private int queuePrefetch;//队列策略
    private int queueBrowserPrefetch;
    private int topicPrefetch;//主题策略
    private int durableTopicPrefetch;
    private int optimizeDurableTopicPrefetch;
    private int maximumPendingMessageLimit;
    public ActiveMQPrefetchPolicy()
    {
        queuePrefetch = 1000;
        queueBrowserPrefetch = 500;
        topicPrefetch = 32767;
        durableTopicPrefetch = 100;
        optimizeDurableTopicPrefetch = 1000;
    }
}

你可能感兴趣的:(activemq)