activemq 消息消费失败之后如何重新消费

在不开启事物的情况下 采用的是应答模式4(ActiveMQSession.AUTO_ACKNOWLEDGE)消费一次 应答一次

这时候消费失败了,由于没有配置死亡队列,消息就不会被消费堆积在队列中,那么怎么才可以让消息再被消费呢?

由于项目中的应用场景,有个方案启动和停止的功能,项目启动启动监听,项目停止,停止监听

具体实现代码如下

public class MqService {

	private JmsTemplate jmsTemplate;

	private CachingConnectionFactory cachingProductConnectionFactory;

	private CachingConnectionFactory cachingConsumersConnectionFactory;

	private static final String ACTIVEMQQUEUE_OPTIMIZATION = "";// 性能优化参数
																// consumer.prefetchSize预加载消息
																// 20条
																// ?consumer.prefetchSize=20

	/**
	 * 发送消息
	 * 
	 * @param ryzhMessage
	 */
	public void send(final RyzhMessage ryzhMessage) {
		
		// 得到MQ工具类
		RyzhMqHolder hodler = mqHolders.get(ryzhMessage.getShcemeId());
		// 发送信息
		jmsTemplate.setConnectionFactory(cachingProductConnectionFactory);
		jmsTemplate.send(hodler.getDestination(), new MessageCreator() {
			public Message createMessage(Session session) throws JMSException {
				ObjectMessage objectMessage = session.createObjectMessage();
				objectMessage.setObject(ryzhMessage);
				return objectMessage;
			}
		});
	}

	/**
	 * 监听
	 * 
	 * @param schemeId
	 * @param receiver
	 */
	public void startListen(RyzhScheme scheme) {
		RyzhMqHolder holder = mqHolders.get(scheme.getSchemeId());
		try {
			if (holder == null) {
				RyzhConsumer consumer = (RyzhConsumer) SpringBeanUtils.getBean("ryzhConsumer");
				consumer.setScheme(scheme);
				logger.info("RyzhMqService-启动消息队列监听器 schemeId=" + scheme.getSchemeId());
				// 如果是为空
				holder = new RyzhMqHolder();
				// 得到整合方案的配置
				TRyzhFa tRyzhFa = ((RyzhConsumer) consumer).getScheme().getZhfa();
				// 得到消息队列配置的信息
				String xxdlJson = tRyzhFa.getXxdlpz();
				// json转map
				RyzhMqConfig ryzhMqConfig = JSON.parseObject(xxdlJson, RyzhMqConfig.class);
				// 设置方案ID
				holder.setSchemeId(scheme.getSchemeId());
				// 设置目的地
				ActiveMQQueue destination = new ActiveMQQueue(RyzhMqConfig.QUEUE_NAME + scheme.getSchemeId() + ACTIVEMQQUEUE_OPTIMIZATION);
				holder.setDestination(destination);
				// 创建监听器
				DefaultMessageListener listener = new DefaultMessageListener();
				// 给监听器设置消费者
				listener.setReceiver(consumer);
				// 将监听器保存在holder中
				holder.setListener(listener);
				// 创建监听容器
				DefaultMessageListenerContainer listenerContainer = new DefaultMessageListenerContainer();
				// 监听容器属性的配置
				listenerContainer.setConnectionFactory(cachingConsumersConnectionFactory);
				// 设置目的地
				listenerContainer.setDestination(destination);
				// 设置监听器
				listenerContainer.setMessageListener(listener);
				// 设置消费者集群数
				listenerContainer.setConcurrentConsumers(ryzhMqConfig.getConcurrentConsumers());
				// 设置监听队列还是主题 默认是队列
				listenerContainer.setPubSubDomain(RyzhMqConfig.PUBSUB_DOMAIN);
				listenerContainer.setPubSubNoLocal(false);
				// listenerContainer.setAcceptMessagesWhileStopping(true);
				// 设置应答模式 默认是4
				listenerContainer.setSessionAcknowledgeMode(RyzhMqConfig.SESSION_ACKNOWLEDGEMODE);
				// 设置是否启动事物 默认不开启
				listenerContainer.setSessionTransacted(RyzhMqConfig.SESSION_TRANSACTED);
				// 将监听容器保存在holder中
				holder.setListenerContainer(listenerContainer);
				// 将holder缓存在map中
				mqHolders.put(scheme.getSchemeId(), holder);
				// 初始化容器
				holder.getListenerContainer().initialize();
				// 启动监听
				holder.getListenerContainer().start();
				logger.info("RyzhMqService-消息队列监听器启动成功 schemeId=" + scheme.getSchemeId());
			}
		} catch (Exception e) {
			logger.error("RyzhMqService-消息队列监听器启动失败 schemeId=" + scheme.getSchemeId(), e);
		}
	}

	public void stopListen(RyzhScheme scheme) {
		RyzhMqHolder ryzhMqHolder = mqHolders.get(scheme.getSchemeId());
		// 停止监听
		ryzhMqHolder.getListenerContainer().destroy();
		// 移除缓存
		mqHolders.remove(scheme.getSchemeId());
	}

	/**
	 * 取得MQHolder
	 * 
	 * @param ryzhMessage
	 * @return
	 */

	public Map getMqHolders() {
		return mqHolders;
	}

	public void setMqHolders(Map mqHolders) {
		this.mqHolders = mqHolders;
	}

	public JmsTemplate getJmsTemplate() {
		return jmsTemplate;
	}

	public void setJmsTemplate(JmsTemplate jmsTemplate) {
		this.jmsTemplate = jmsTemplate;
	}

	public CachingConnectionFactory getCachingProductConnectionFactory() {
		return cachingProductConnectionFactory;
	}

	public void setCachingProductConnectionFactory(CachingConnectionFactory cachingProductConnectionFactory) {
		this.cachingProductConnectionFactory = cachingProductConnectionFactory;
	}

	public CachingConnectionFactory getCachingConsumersConnectionFactory() {
		return cachingConsumersConnectionFactory;
	}

	public void setCachingConsumersConnectionFactory(CachingConnectionFactory cachingConsumersConnectionFactory) {
		this.cachingConsumersConnectionFactory = cachingConsumersConnectionFactory;
	}

}

具体的xml配置如下





	
		
		
		
		
		
		
		
	

	
		
		
		
	

	
		
		
		
		
		
	
	
	
		
		
		
	
	
	
		
		
		
		
		
	
	
		
		
		
		
		
				
				
			
		
		-->
 
  
注意红色部分,需要缓存,否则监听会被缓存无法stop。

以下就可以达到不用配置死信队列就可以重新消费信息。(其实原理就是重启了监听容器)


你可能感兴趣的:(其他)