rabbitMQ消息服务器学习笔记(java)1

【1】 - Hello World

      哈哈,看到hello Word 是不是很熟悉,对,不管学什么请先从这个问候开始;

       RabbitMQ是消息代理。从本质上说,它接受来自生产者的信息,并将它们传递给消费者。在两者之间,它可以根据你给它的路由,缓冲规则进行传递消息。
       如果你的工作中需要用到RabbitMQ,那么我建议你先在电脑上安装好RabbitMQ服务器,然后打开eclipse,跟这我的教程一步步的学习RabbitMQ,这样你会对RabbitMQ有一个全面的认识,而且能打好一个很好的基础。如果你只是了解一下,那就随便看看吧。

转自:http://blog.csdn.net/chwshuang/article/details/50521708(本篇作为收藏,作为自己使用笔记!)

我的开发环境:

操作系统: Windows7 64bit 

开发环境: JDK 1.7 - 1.7.0_55

开发工具: Eclipse Kepler SR2

RabbitMQ版本:  3.6.0

Elang版本: erl7.2.1

关于Windows7下安装RabbitMQ的教程:

http://blog.csdn.net/liangwanmian/article/details/78516824点击打开链接

源码地址

https://github.com/libolibolibo/rabbitmq-master.git点击打开链接


一、专业术语

关于rabbitmq的架构请看
http://blog.csdn.net/liangwanmian/article/details/78523436点击打开链接

1. 生产者:


       在现实生活中就好比制造商品的工厂,他们是商品的生产者。生产者只意味着发送。发送消息的程序称之为一个生产者。我们用“P”表示: 


2. 队列:

        队列就像存放商品的仓库或者商店,是生产商品的工厂和购买商品的用户之间的中转站。队列就像是一个仓库或者流水线。在RabbitMQ中,信息流从你的应用程序出发,来到RabbitMQ的队列,所有信息可以只存储在一个队列中。队列可以存储很多的消息,因为它基本上是一个无限制的缓冲区,前提是你的机器有足够的存储空间。多个生产者可以将消息发送到同一个队列中,多个消费者也可以只从同一个队列接收数据。这就是队列的特性。队列用下面的图表示,图上面是队列的名字: 


3. 消费者

        消费者就好比是从商店购买或从仓库取走商品的人,消费的意思就是接收。消费者是一个程序,主要是等待接收消息。我们的用“C”表示 



注意:

        生产者,消费者和队列(RabbitMQ)不必部署在同一台机器上。实际在生产环境的大多数应用中,他们都是分开部署的。




二、“Hello World”

1. 说明

        在本教程中,我们我们通过2个java程序,一个发送消息的生产者,和一个接收信息并打印的消费者。想要了解rabbitmq,必须了解一些最基础的内容,我们先从一些代码片段来了解产生信息和接收消息的流程和方法。在编写代码前,我们先来用户一张图表示要做的事,在下图中,“P”是我们的生产者,“C”是我们的消费者。在中间红色框是代表RabbitMQ中的一个消息队列。箭头指向表示信息流的方向。 

                                                                                                                                                    


2. 项目目录 

        在eclipse中创建一个rabbitmq的java项目,然后在项目下建一个名为lib的source folder, 然后将rabbitmq官网下载的rabbitmq-java-client-bin-3.6.0.rar解压出rabbitmq-client.jar拷贝到lib目录,如果创建的是Maven项目,只需要添加如下依赖:

[plain] view plain copy
  1. <dependencies>  
  2.         <dependency>  
  3.             <groupId>com.rabbitmq</groupId>  
  4.             <artifactId>amqp-client</artifactId>  
  5.             <version>3.6.0</version>  
  6.         </dependency>  
  7.         ... ...  
  8.     </dependencies>  
创建一个maven项目如下:


3.  消息生产者

/**
 * TODO
 * 
 */
package com.aitongyi.rabbitmq.helloworld;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
 * 消息生产者
 * @author hushuang
 *
 */
public class P {
	//队列的名称
  private final static String QUEUE_NAME = "hello";

  public static void main(String[] argv) throws Exception {
   //创建一个链接工程
	  ConnectionFactory factory = new ConnectionFactory();
    factory.setHost("localhost");
    //通过工厂创建一个新的链接
    Connection connection = factory.newConnection();
    //通过tcp链接创建一个通道
    Channel channel = connection.createChannel();
    //声明一个队列
    /*
     * 声明一个队列 -- 在RabbitMQ中,队列声明是幂等性的
     * (一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同),
     * 也就是说,如果不存在,就创建,如果存在,不会对已经存在的队列产生任何影响。   
     */
    /*
 Queue.DeclareOk queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete,
                                 Map<String, Object> arguments) throws IOException;
     *  durable:true、false true:在服务器重启时,能够存活
		exclusive :是否为当前连接的专用队列,在连接断开后,会自动删除该队列,生产环境中应该很少用到吧。
		autodelete:当没有任何消费者使用时,自动删除该队列
     */
    channel.queueDeclare(QUEUE_NAME, false, false, false, null);
    String message = "Hello World!";
//  发送消息到队列中  
    /*
void basicPublish(String exchange, String routingKey, boolean mandatory, boolean immediate, BasicProperties props, byte[] body)
throws IOException;
*	routingKey:路由键,#匹配0个或多个单词,*匹配一个单词,在topic exchange做消息转发用
	mandatory:true:如果exchange根据自身类型和消息routeKey无法找到一个符合条件的queue,
那么会调用basic.return方法将消息返还给生产者。false:出现上述情形broker会直接将消息扔掉
	immediate:true:如果exchange在将消息route到queue(s)时发现对应的queue上没有消费者,
那么这条消息不会放入队列中。当与消息routeKey关联的所有queue(一个或多个)都没有消费者时,该消息会通过basic.return方法返还给生产者。
	BasicProperties :需要注意的是BasicProperties.deliveryMode,0:不持久化 1:持久化 
这里指的是消息的持久化,配合channel(durable=true),queue(durable)可以实现,即使服务器宕机,消息仍然保留
	简单来说:mandatory标志告诉服务器至少将该消息route到一个队列中,
否则将消息返还给生产者;immediate标志告诉服务器如果该消息关联的queue上有消费者,
则马上将消息投递给它,如果所有queue都没有消费者,直接把消息返还给生产者,不用将消息入队列等待消费者了
*
     */
    channel.basicPublish("", QUEUE_NAME, null, message.getBytes("UTF-8"));
    System.out.println("P [x] Sent '" + message + "'");

    channel.close();
    connection.close();
  }
}

4. 消息消费者

/**
 * TODO
 * 
 */
package com.aitongyi.rabbitmq.helloworld;

import com.rabbitmq.client.*;
import java.io.IOException;

/**
 * 消息消费者
 * 
 * @author hushuang
 * 
 */
public class C {

	private final static String QUEUE_NAME = "hello";

	public static void main(String[] argv) throws Exception {
		//创建工厂
		ConnectionFactory factory = new ConnectionFactory();
		//设置rabbitmq地址
		factory.setHost("localhost");
		//创建一个新的链接
		Connection connection = factory.newConnection();
		//通过链接创建一个通道
		Channel channel = connection.createChannel();
		// 声明要关注的队列 -- 在RabbitMQ中,队列声明是幂等性的(一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同),
		//也就是说,如果不存在,就创建,如果存在,不会对已经存在的队列产生任何影响。
		/*
		 * Queue.DeclareOk queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete,
                                 Map<String, Object> arguments) throws IOException;
     *  durable:true、false true:在服务器重启时,能够存活
		exclusive :是否为当前连接的专用队列,在连接断开后,会自动删除该队列,生产环境中应该很少用到吧。
		autodelete:当没有任何消费者使用时,自动删除该队列
		 * 
		 */
		channel.queueDeclare(QUEUE_NAME, false, false, false, null);
		System.out.println("C [*] Waiting for messages. To exit press CTRL+C");
		/*
		 * DefaultConsumer类实现了Consumer接口,通过传入一个频道,告诉服务器我们需要那个频道的消息,如果频道中有消息,就会执行回调函数handleDelivery  
		 * 
		 */
		Consumer consumer = new DefaultConsumer(channel) {
			@Override
			public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
				String message = new String(body, "UTF-8");
				System.out.println("C [x] Received '" + message + "'");
			}
		};
		/*
		 *     String basicConsume(String queue, boolean autoAck, Consumer callback) throws IOException;
		 *     autoAck:是否自动ack,如果不自动ack,需要使用channel.ack、channel.nack、channel.basicReject 进行消息应答
		 * 
		 */
		channel.basicConsume(QUEUE_NAME, true, consumer);
	}
}

5. 运行测试


        如果在windows7下,你需要先双击【RabbitMQ Server\rabbitmq_server-3.6.0\sbin】目录下的rabbitmq-server.bat,来启动RabbitMQ服务。负责,运行我们的程序时,会提示【java.net.ConnectException: Connection refused: connect】

C [*] Waiting for messages. To exit press CTRL+CC [x] Received 'Hello World!'
        先运行消费者服务器来关注【hello】这个队列的情况。

[plain]  view plain  copy
  1. C [*] Waiting for messages. To exit press CTRL+C  

C [*] Waiting for messages. To exit press CTRL+CC [x] Received 'Hello World!'
        然后再运行生产者端,发送消息到队列中:

[plain]  view plain  copy
  1. P [x] Sent 'Hello World!'  

C [*] Waiting for messages. To exit press CTRL+CC [x] Received 'Hello World!'
        再切换到消费者端的控制台,查看日志:

[plain]  view plain  copy
  1. C [*] Waiting for messages. To exit press CTRL+C  
  2. C [x] Received 'Hello World!'  






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值