消息队列——rabbitmq学习

消息队列与rpc的区别在于,消息队列不返回数据,rpc可以,但是由于消息队列不用返回数据,所以在不希望发送端的速度受制于接收端且不用返回数据时,使用消息队列是很方便的。

进入正文:

由于rabbitmq是基于erlang语言编写的,因此需要安装erlang。进入erlang官网:http://www.erlang.org/downloads下载。安装的方法很简单,一路默认就ok了。

然后是安装rabbitmq,官网地址:http://www.rabbitmq.com/install-windows.html

根据需要进行下载。

安装rabbitmq需要特别注意的一点是:一定要更改rabbitmq的安装地址,因为其默认安装地址是C:\Program Files,但是很坑的一点是rabbitmq自己并不解析带有空格的路径,其他还好默认就行。

安装好了以后打开cmd,cd到安装路径下的sbin文件夹下输入命令:rabbitmq-plugins enable rabbitmq_management安装插件,这样可以在页面端访问localhost:15672来访问rabbitmq。

如果可以访问代表你安装成功,接着是如何在代码中使用了。

pom文件中需要加上下面几个包:

<dependency>
			<groupId>com.rabbitmq</groupId>
			<artifactId>amqp-client</artifactId>
			<version>4.1.0</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.amqp</groupId>
			<artifactId>spring-rabbit</artifactId>
			<version>1.7.5.RELEASE</version>
		</dependency>

applicationContext.xml中需要加入与rabbitmq相关的配置:

<!--配置connection-factory,指定连接rabbit server参数这里有个坑,rabbitmq的15672是管理界面的访问端口,远程访问端口是5672 -->
	<rabbit:connection-factory id="connectionFactory" host="127.0.0.1" port="5672" username="pan" password="123456" />


	<!--通过指定下面的admin信息,当前producer中的exchange和queue会在rabbitmq服务器上自动生成 -->
	<rabbit:admin connection-factory="connectionFactory" />


	<!--定义queue -->
	<!-- durable 是否持久化 exclusive 仅创建者可以使用的私有队列,断开后自动删除 auto-delete 当所有消费端连接断开后,是否自动删除队列 -->
	<rabbit:queue name="queueTest" durable="true" auto-delete="false" exclusive="false" />


	<!-- 交换机定义 -->
	<!-- 交换机:一个交换机可以绑定多个队列,一个队列也可以绑定到多个交换机上。 如果没有队列绑定到交换机上,则发送到该交换机上的信息则会丢失。 
		direct模式:消息与一个特定的路由器完全匹配,才会转发 topic模式:按模式匹配 -->
	<rabbit:direct-exchange name="exchangeTest" durable="true" auto-delete="false">
		<rabbit:bindings>
			<rabbit:binding queue="queueTest" key="queueTestKey"></rabbit:binding>
		</rabbit:bindings>
	</rabbit:direct-exchange>


	<!--定义rabbit template用于数据的接收和发送 -->
	<rabbit:template id="amqpTemplate" connection-factory="connectionFactory" exchange="exchangeTest" />

	<!-- 消息接收者 -->
	<bean id="messageReceiver" class="org.pan.rabbitmq.rabbitmq.MessageConsumer"></bean>

	<!-- queue litener 观察 监听模式 当有消息到达时会通知监听在对应的队列上的监听对象 -->
	<rabbit:listener-container connection-factory="connectionFactory">
		<!-- queues 监听队列,多个用逗号分隔 ref 监听器 -->
		<rabbit:listener queues="queueTest" ref="messageReceiver" />
	</rabbit:listener-container>

上面这个配置文件的头上需要多添加下面的内容:

    xmlns:rabbit="http://www.springframework.org/schema/rabbit"
	
    http://www.springframework.org/schema/rabbit
    http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd

这里需要注意两个端口:15672是页面访问rabbitmq的端口,代码如果要远程连接rabbitmq是5672端口。

连接的用户名和密码rabbitmq有一个默认的是:guest,guest。可以通过15672页面来创建用户,至于方法网上有很多教程,有兴趣的朋友可以自己去找找看。

然后是生产者代码:

/**
 * @description
 * @auth panmingshuai
 * @time 2018年3月24日下午10:21:18
 * 
 */

@Service
public class MessageProducer {
	private Logger logger = LoggerFactory.getLogger(MessageProducer.class);

	@Resource(name = "amqpTemplate")
	private AmqpTemplate amqpTemplate;

	public void sendMessage(Object message) throws IOException {
		logger.info("to send message:{}", message);
		amqpTemplate.convertAndSend("queueTestKey", message);
	}
}

消费者代码:

/**
 * @description
 * @auth panmingshuai
 * @time 2018年3月24日下午10:23:38
 * 
 */

public class MessageConsumer implements MessageListener {
	private Logger logger = LoggerFactory.getLogger(MessageConsumer.class);

	@Override
	public void onMessage(Message message) {
		logger.info("consumer receive message------->:{}", (User)SerializationUtils.deserialize(message.getBody()));
	}
	
	
}

因为网上的资料都是传字符串的,我就弄了个穿对象的。User代码如下:

/**
 *@description 
 *@auth panmingshuai
 *@time 2018年3月29日下午11:27:30
 * 
 */

public class User implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Integer age;
	private String name;
	
	public User() {
	}
	public User(Integer age, String name) {
		this.age = age;
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public String toString() {
		return "User [age=" + age + ", name=" + name + "]";
	}
	
}

最后是发送消息的Controller

/**
 *@description 
 *@auth panmingshuai
 *@time 2018年3月24日下午10:26:21
 * 
 */
@Controller
@RequestMapping("/rabbit")
public class RabbitController {
	
	@Autowired
	private MessageProducer producer;
	
	@RequestMapping("/msg")
	@ResponseBody
	public String getMsg() throws IOException{
		int a = 100;  
        while (a > 0) {  
        	producer.sendMessage(new User(a, "pan"+a--));  
        	
            try {  
                //让子弹飞一会儿 
                Thread.sleep(1000);  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }
        }
        return "发送完毕";
	}
}

运行之后日志效果如下:

2018-03-30 00:44:22,913 [qtp1651855867-17] INFO  [org.pan.rabbitmq.rabbitmq.MessageProducer] - to send message:User [age=100, name=pan100]
2018-03-30 00:44:22,931 [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer#0-1] INFO  [org.pan.rabbitmq.rabbitmq.MessageConsumer] - consumer receive message------->:User [age=100, name=pan100]
2018-03-30 00:44:23,925 [qtp1651855867-17] INFO  [org.pan.rabbitmq.rabbitmq.MessageProducer] - to send message:User [age=99, name=pan99]
2018-03-30 00:44:23,933 [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer#0-1] INFO  [org.pan.rabbitmq.rabbitmq.MessageConsumer] - consumer receive message------->:User [age=99, name=pan99]
2018-03-30 00:44:24,926 [qtp1651855867-17] INFO  [org.pan.rabbitmq.rabbitmq.MessageProducer] - to send message:User [age=98, name=pan98]
2018-03-30 00:44:24,931 [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer#0-1] INFO  [org.pan.rabbitmq.rabbitmq.MessageConsumer] - consumer receive message------->:User [age=98, name=pan98]
2018-03-30 00:44:25,926 [qtp1651855867-17] INFO  [org.pan.rabbitmq.rabbitmq.MessageProducer] - to send message:User [age=97, name=pan97]
2018-03-30 00:44:25,929 [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer#0-1] INFO  [org.pan.rabbitmq.rabbitmq.MessageConsumer] - consumer receive message------->:User [age=97, name=pan97]
2018-03-30 00:44:26,927 [qtp1651855867-17] INFO  [org.pan.rabbitmq.rabbitmq.MessageProducer] - to send message:User [age=96, name=pan96]
2018-03-30 00:44:26,929 [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer#0-1] INFO  [org.pan.rabbitmq.rabbitmq.MessageConsumer] - consumer receive message------->:User [age=96, name=pan96]
2018-03-30 00:44:27,927 [qtp1651855867-17] INFO  [org.pan.rabbitmq.rabbitmq.MessageProducer] - to send message:User [age=95, name=pan95]
2018-03-30 00:44:27,929 [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer#0-1] INFO  [org.pan.rabbitmq.rabbitmq.MessageConsumer] - consumer receive message------->:User [age=95, name=pan95]
2018-03-30 00:44:28,927 [qtp1651855867-17] INFO  [org.pan.rabbitmq.rabbitmq.MessageProducer] - to send message:User [age=94, name=pan94]
2018-03-30 00:44:28,931 [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer#0-1] INFO  [org.pan.rabbitmq.rabbitmq.MessageConsumer] - consumer receive message------->:User [age=94, name=pan94]
2018-03-30 00:44:29,928 [qtp1651855867-17] INFO  [org.pan.rabbitmq.rabbitmq.MessageProducer] - to send message:User [age=93, name=pan93]
2018-03-30 00:44:29,932 [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer#0-1] INFO  [org.pan.rabbitmq.rabbitmq.MessageConsumer] - consumer receive message------->:User [age=93, name=pan93]

猜你喜欢

转载自my.oschina.net/u/3534905/blog/1787242