rabbitmq

关于rabbitmq的自己的一点小总结

  • 1.路由问题exchange(简单介绍常用的三种路由direct,topic,fanout)
  • 2.死信问题

spring -pom配置

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>rabbitmq-spring</groupId>
  <artifactId>rabbitmq-spring</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
      <properties>  
            <rabbitmq.version>3.0.4</rabbitmq.version>  
            <spring.amqp.version>1.3.9.RELEASE</spring.amqp.version>  
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
            <spring.version>3.1.2.RELEASE</spring.version>  
        </properties>  
        <dependencies>  
            <dependency>  
                <groupId>com.rabbitmq</groupId>  
                <artifactId>amqp-client</artifactId>  
                <version>${rabbitmq.version}</version>  
            </dependency>  
      
            <dependency>  
                <groupId>org.springframework.amqp</groupId>  
                <artifactId>spring-rabbit</artifactId>  
                <version>${spring.amqp.version}</version>  
            </dependency>  
      
            <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-core</artifactId>  
                <version>${spring.version}</version>  
                <exclusions>  
                    <!-- Exclude Commons Logging in favor of SLF4j -->  
                    <exclusion>  
                        <groupId>commons-logging</groupId>  
                        <artifactId>commons-logging</artifactId>  
                    </exclusion>  
                </exclusions>  
            </dependency>  
            <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-context</artifactId>  
                <version>${spring.version}</version>  
            </dependency>  
      
            <dependency>  
                <groupId>org.springframework</groupId>  
                <artifactId>spring-test</artifactId>  
                <version>${spring.version}</version>  
                <scope>test</scope>  
            </dependency>  
      
            <dependency>  
                <groupId>junit</groupId>  
                <artifactId>junit</artifactId>  
                <version>4.8.1</version>  
                <scope>test</scope>  
            </dependency>  
      
            <dependency>  
                <groupId>org.springframework.amqp</groupId>  
                <artifactId>spring-amqp</artifactId>  
                <version>${spring.amqp.version}</version>  
                <classifier>sources</classifier>  
                <scope>compile</scope>  
            </dependency>  
            <dependency>  
                <groupId>commons-lang</groupId>  
                <artifactId>commons-lang</artifactId>  
                <version>2.6</version>  
            </dependency>  
            <dependency>
				<groupId>com.google.code.gson</groupId>
				<artifactId>gson</artifactId>
				<version>2.4</version>
			</dependency>
            <dependency>  
                <groupId>org.slf4j</groupId>  
                <artifactId>slf4j-api</artifactId>  
                <version>1.5.10</version>  
            </dependency>  
            <dependency>  
                <groupId>org.slf4j</groupId>  
                <artifactId>jcl-over-slf4j</artifactId>  
                <version>1.5.10</version>  
                <scope>runtime</scope>  
            </dependency>  
            <dependency>  
                <groupId>org.slf4j</groupId>  
                <artifactId>slf4j-log4j12</artifactId>  
                <version>1.5.10</version>  
                <scope>runtime</scope>  
            </dependency>  
            <dependency>  
                <groupId>log4j</groupId>  
                <artifactId>log4j</artifactId>  
                <version>1.2.14</version>  
                <scope>runtime</scope>  
            </dependency>  
            <dependency>  
                <groupId>org.aspectj</groupId>  
                <artifactId>aspectjweaver</artifactId>  
                <version>1.6.9</version>  
            </dependency>  
        </dependencies>  
  
</project>

###spring-rabbit.xml配置

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc"  
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"  
    xmlns:websocket="http://www.springframework.org/schema/websocket"  
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:cache="http://www.springframework.org/schema/cache"  
    xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:rabbit="http://www.springframework.org/schema/rabbit"  
    xmlns:task="http://www.springframework.org/schema/task"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
    http://www.springframework.org/schema/beans/spring-beans.xsd  
    http://www.springframework.org/schema/mvc  
    http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd  
    http://www.springframework.org/schema/aop  
    http://www.springframework.org/schema/aop/spring-aop-4.1.xsd  
    http://www.springframework.org/schema/context  
    http://www.springframework.org/schema/context/spring-context-4.1.xsd  
    http://www.springframework.org/schema/cache  
    http://www.springframework.org/schema/cache/spring-cache-4.1.xsd  
    http://www.springframework.org/schema/tx  
    http://www.springframework.org/schema/tx/spring-tx-4.1.xsd  
    http://www.springframework.org/schema/websocket  
    http://www.springframework.org/schema/websocket/spring-websocket-4.1.xsd  
    http://www.springframework.org/schema/data/jpa  
    http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd  
    http://www.springframework.org/schema/jdbc  
    http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd  
    http://www.springframework.org/schema/rabbit  
    http://www.springframework.org/schema/rabbit/spring-rabbit-1.4.xsd  
    http://www.springframework.org/schema/task  
    http://www.springframework.org/schema/task/spring-task-4.1.xsd">     
  
    <!-- 创建connectionFactory -->  
 <bean id="rabbitConnectionFactory"  
        class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">  
       <constructor-arg value="127.0.0.1"/>
        <property name="username" value="admin"/>
       <property name="password" value="password"/>
       <property name="virtualHost" value="/"/>
       <!-- 下面根据需求定义-->
        <property name="connectionTimeout" value="10000"/>
        <property name="channelCacheSize" value="5"/>
     </bean> 
      <!-- 创建rabbitAdmin 代理类 --> 
      <bean id="rabbitAdmin" class="org.springframework.amqp.rabbit.core.RabbitAdmin">  
           <constructor-arg ref="rabbitConnectionFactory" /> 
           <!-- chanel缓存数量 -->
           <property name="channelCacheSize" value="25" />  
         </bean> 
         <!-- 创建rabbitTemplate 消息模板类 若不绑定exchang,routingKey则发布消息时需要手动传入exchang,routingKey -->
         <bean id="rabbitTemplate" class="org.springframework.amqp.rabbit.core.RabbitTemplate" >
       <constructor-arg ref="rabbitConnectionFactory"/>
     <!-- 
     <property name="exchange" value="directExchangeTest" />
 <property name="routingKey" value="directRoutingKey"/>
         -->
         </bean>
         
<!-- 声明Queue并设定Queue的名称    durable是否持久化 auto-delete自动删除,没有任何消费者订阅就自动删除 exclusive排他 -->  
<rabbit:queue name="task_queue"  durable="true" auto-delete="false"  exclusive="false" declared-by="rabbitAdmin" /> 	
<rabbit:queue name="hello"  durable="true" auto-delete="false"  exclusive="false" declared-by="rabbitAdmin" > 	
    <rabbit:queue-arguments >
        <!-- 死信路由器  -->
       <entry key="x-dead-letter-exchange" value="dead-letter-exchange" />
        <!-- 死信路由routingKey-->
      <entry key="x-dead-letter-routing-key" value="hello" />
      <!-- 消息TTL过期 做延迟消费-->
      <entry key="x-message-ttl">
       <value type="java.lang.Long">50000</value>
      </entry>
     <!--队列达到最大长度 ,超过最大长度就会丢失 -->
      <entry key="x-max-length">
        <value type="java.lang.Long">100</value>  
     </entry>
   </rabbit:queue-arguments>

<rabbit:queue name="alter_message"  durable="true" auto-delete="false"  exclusive="false" declared-by="rabbitAdmin" /> 	
<rabbit:queue name="dead" durable="true" auto-delete="false"  exclusive="false" declared-by="rabbitAdmin" />

<!-- 声明业务路由-->
<rabbit:topic-exchange name="testEx" durable="true" auto-delete="false" declared-by="rabbitAdmin" >
<rabbit:exchange-arguments >
<!-- alternate-exchange属性所有与业务路由不匹配的消息路由到名为alter的AE路由  -->
  <entry key="alternate-exchange" value="alter" />
 </rabbit:exchange-arguments>
 <rabbit:bindings>
 <!--绑定routingKey,queue -->
 <rabbit:binding queue="hello" pattern="hello"></rabbit:binding>
 <rabbit:binding queue="task_queue" pattern="task_queue"></rabbit:binding>
</rabbit:bindings>
</rabbit:topic-exchange>

<!-- 定义死信路由-->
 <rabbit:topic-exchange name="dead-letter-exchange" durable="true" auto-delete="false" declared-by="rabbitAdmin" >
 <rabbit:bindings> 
     <!-- queue的 routingKey 为路由到死信路由的queue中的 x-dead-letter-routing-key属性的值本例中为路由message到死信的queue为hello-->
     <rabbit:binding queue="dead" pattern="hello"></rabbit:binding>
</rabbit:bindings>
</rabbit:topic-exchange>

<!-- 定义警告队列-->
 <rabbit:fanout-exchange name="alter">
     	<rabbit:exchange-arguments >
       <!-- 是否是内部路由 true客户端不能发布消息到此交换机,只能通过其他交换机一起使用  -->
    		<entry key="internal" value="true" />
    	</rabbit:exchange-arguments>
    	<rabbit:bindings>
    		<rabbit:binding queue="alter_message"/>	
    	</rabbit:bindings>
</rabbit:fanout-exchange>

<!-- 定义监听器工厂-->
<bean id="rabbitListenerContainerFactory" class="org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory">  
        <property name="connectionFactory" ref="rabbitConnectionFactory" />  
        <property name="transactionManager" ref="transactionManager" />  
        <property name="concurrentConsumers" value="1" />  
        <property name="maxConcurrentConsumers" value="10" />  
     <!-- 其他视需求添加-->
     <!-- 
     <property name="messageConverter" ref="jsonMessageConverter" />  
        <property name="taskExecutor" ref="taskExecutor" />  
        <property name="channelTransacted" value="true" />  
        <property name="adviceChain">  
            <array>  
                <ref bean="retryInterceptor" />  
            </array>  
        </property> 
        -->
</bean> 

<!-- 定义监听器容器-->
<!-- acknowledge应答方式默认为true自动应答,这里选择手动应答 prefetch 一次取queue中message数量-->
  <rabbit:listener-container connection-factory="rabbitConnectionFactory" acknowledge="manual" prefetch="1">  
   <rabbit:listener queues="directQueue1" ref="directQueueMessageListener" /> 
   <rabbit:listener queues="topicQueue"  ref="topicQueueMessageListener" /> 
   <rabbit:listener queues="fanoutQueue1" ref="fanoutQueueMessageListener"/>
   <rabbit:listener queues="hello" ref="topicQueueMessageListener" /> 
</rabbit:listener-container>

生产者发布消息

package rabbitmq.producer.biz.impl;

import java.io.IOException;

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import rabbitmq.producer.biz.MessageProducerBiz;

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.ReturnListener;

/**
 * 文件名:MessageProducer.java
 * 描述:
 * 作者:gustar
 * 日期:2017年6月27日下午2:37:41
 */
@Service("messageProducerBiz")
public class MessageProducerBizImpl implements MessageProducerBiz {

	@Autowired
	private AmqpTemplate rabbitTemplate;

	@Autowired
	private CachingConnectionFactory rabbitConnectionFactory;

	/**
	 * 发布 message
	 * rabbitTemplate绑定exchange,routingKey属性值
	 * @param message
	 */
	public void mqRoute(Object message) {
		/*如果rabbitTemplate未绑定exchange和routingKey采用此发送发送回丢失消息应采用下面方式*/
		rabbitTemplate.convertAndSend(message);
	}

	/**
	 * 发布 message
	 * @param exchange 路由器
	 * @param routingKey 路由规则
	 * @param message
	 * 作者:gustar
	 * 日期:2017年6月29日上午11:33:10
	 */
	public void mqRoute(String exchange, String routingKey, Object message) {
		rabbitTemplate.convertAndSend(exchange, routingKey, message);

	}

	/**
	 * 基于RPC(远程调用等待消息回复)
	 * @param exchange 路由器
	 * @param routingKey 路由规则
	 * @param message
	 * 作者:gustar
	 * 日期:2017年6月28日上午10:47:28
	 */
	public Object sendAndReceive(String exchange, String routingKey, Object message) {
		return rabbitTemplate.convertSendAndReceive(message);
	}
}
	

消费者消费消息

package rabbitmq.consumer.queue.listener;

import java.io.IOException;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;

import rabbitmq.util.GlobalVar;

import com.rabbitmq.client.Channel;

/**
 * 文件名:TopicMessageListener.java
 * 描述:
 * 作者:gustar
 * 日期:2017年6月27日下午2:27:14
 */
@Component("topicQueueMessageListener")
public class TopicQueueMessageListener implements ChannelAwareMessageListener {

	public void onMessage(Message message, Channel channel) throws IOException {
		// Object obj = null;
		String messageHandleStatus = "MESSAGE_HANDLE_ACCEPT";
		try {
			// obj = msgConverter.fromMessage(message);
			System.out.println("TopicQueueMessageListener onMessage method do topic--" + message);
		} catch (Exception e) {
			// 根据异常种类决定是ACCEPT、RETRY还是 REJECT

		} finally {
			if ("MESSAGE_HANDLE_ACCEPT".equals(messageHandleStatus)) {
				// 确认消息,false只确认当前一个消息收到,true确认所有consumer获得的消息
				channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
			} else if ("MESSAGE_HANDLE_RETRY".equals(messageHandleStatus)) {
				// ack返回false,并重新回到队列 第一个boolean参数:是否批量 ,第二个参数:被拒绝的是否重新入队列
				channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
			} else {
			
				/** 拒绝消息 ,回死信队列 */
			channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
			}
		}

	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值