RabbitMQ HelloWorld

RabbitMQ HelloWorld

介绍

RabbitMQ 是一个消息队列 : 他接收和转发消息 . 我们可以把他看做邮局,当您要发布的邮件放到邮箱时,我们只要确定邮件发送给哪个收件人,然后最终 RabbitMQ 会将邮件发送给收件人,而 RabbitMQ 就相当于一个邮箱,邮局和邮递员.与邮局的区别在于,邮局处理的是纸张, 而 RabbitMQ 处理的是二进制的 Blob 数据 - 消息.

术语

Procecing 意味着仅仅是发送, 一个发送消息的程序就是一个生产者.

Queue : 队列是 RabbitMQ 中的一个"邮箱"的名字,消息只能存储在队列中,它的本质是一个大的消息缓冲区,许多生产者可以发送到一个队列的消息, 并且许多消费者可以尝试从一个队列接收数据.

Consuming 意思和接收相似, 一个消费者就是一个程序主要用来等待接收信息.

在这里插入图片描述

Hello World

生产者

在这里插入图片描述

步骤
  • 导入 jar 包
    • amqp-client-5.6.0.jar
    • slf4j-api-1.7.26.jar
    • slf4j-simple-1.7.26.jar
  • 编写 Producer.java
package com.fly.rabbimq.producer;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

/**
 * 生产者
 * 
 * @author 李凡宇
 *
 */
public class Producer {
	
	// 1.声明队列的名字
	public final static String QUEUE = "hello";
	
	public static void main(String[] args) {
		
		// 2.创建一个与服务器交互的连接
		// 2-1.创建与服务器交互的连接工厂
		ConnectionFactory factory = new ConnectionFactory();
		// 2-2.设置服务器的地址
		factory.setHost("localhost");
		Connection connection = null;
		Channel channel = null;
		try {
			// 2-3.在工厂中获得一个连接
			connection = factory.newConnection();
			// 2-4.在连接中获得一个通道
			channel = connection.createChannel();
			// 2-5.声明队列
			/**
             * 声明队列,如果Rabbit中没有此队列将自动创建
             * param1:队列名称
             * param2:是否持久化
             * param3:队列是否独占此连接
             * param4:队列不再使用时是否自动删除此队列
             * param5:队列参数
             */
			channel.queueDeclare(QUEUE, false, false, false, null);
			// 2-6.要发送的消息
			String message = "hello world";
			// 2-7.进行发布
			/**
             * 消息发布方法
             * param1:Exchange的名称,如果没有指定,则使用Default Exchange
             * param2:routingKey,消息的路由Key,是用于Exchange(交换机)将消息转发到指定的消息队列
             * param3:消息包含的属性
             * param4:消息体
			 * 这里没有指定交换机,消息将发送给默认交换机,每个队列也会绑定那个默认的交换机,但是不能显示绑定或解除绑定
             * 默认的交换机,routingKey等于队列名称
             */
			channel.basicPublish("", QUEUE, null, message.getBytes());
			System.out.println("send : "+ message);
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			if(channel != null){
				try {
					channel.close();
				} catch (IOException e) {
					e.printStackTrace();
				} catch (TimeoutException e) {
					e.printStackTrace();
				}
			}
			if(connection != null){
				try {
					connection.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}	
    
}
  • 启动 RabbitMQ 的 server 端

在这里插入图片描述

  • 运行 Producer 文件

在这里插入图片描述

  • 观察队列

在这里插入图片描述

消费者

在这里插入图片描述

步骤
  • 导入 jar 包
    • amqp-client-5.6.0.jar
    • slf4j-api-1.7.26.jar
    • slf4j-simple-1.7.26.jar
  • 编写 Receive.java
package com.fly.rabbitmq.consumer;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.AMQP.BasicProperties;

/**
 * 消费者
 * 
 * @author 李凡宇
 *
 */
public class Consumer {
	
	// 1.声明队列的名字
	public final static String QUEUE = "hello";
	
	public static void main(String[] args) {
		
		// 2.创建一个与服务器交互的连接
		// 2-1.创建与服务器交互的连接工厂
		ConnectionFactory factory = new ConnectionFactory();
		// 2-2.设置服务器的地址
		factory.setHost("127.0.0.1");
		Connection connection = null;
		Channel channel = null;
		try {
			connection = factory.newConnection();
			channel = connection.createChannel();
			// 2-3.声明队列
			channel.queueDeclare(QUEUE, false, false, false, null);
			// 2-4.定义消费方法
			DefaultConsumer consumer = new DefaultConsumer(channel){
				@Override
				public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties 																								properties,
						byte[] body) throws IOException {
					//交换机
					String exchange = envelope.getExchange();
					 //路由key
					String routingKey = envelope.getRoutingKey();
					//消息id
					long deliveryTag = envelope.getDeliveryTag();
					//消息内容
					String msg = new String(body);
					System.out.println("receive message.." + msg);
				}
			};
			// 2-5.监听队列
			/**
	         * 监听队列String queue, boolean autoAck,Consumer callback
	         * 参数明细
	         * 1、队列名称
	         * 2、是否自动回复,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置为false则需要手				  动回复
	         * 3、消费消息的方法,消费者接收到消息后调用此方法
	         */
			channel.basicConsume(QUEUE,true,consumer);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (TimeoutException e) {
			e.printStackTrace();
		}
	}
}
测试

先观察浏览器中准备推送的消息记录有几条,下图中有0条

在这里插入图片描述

启动生产者 再次观察浏览器,发现待发送的消息有一条,增加了一条

在这里插入图片描述

在这里插入图片描述

启动消费者 可以观察到又恢复成了 0 条 , 说明我们的测试成功 .

在这里插入图片描述

在这里插入图片描述

注意

编写过程中要保证生产者与消费者的 QUEUE 的声明保持一致,否则会出现 406 错误 .

即 :

//二者要保持一致
Producer :
channel.queueDeclare(QUEUE, false, false, false, null);
Consumer :
channel.queueDeclare(QUEUE, false, false, false, null);

否则会出现如下错误 :

java.io.IOException
	at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:129)
	at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:125)
	at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:147)
	at com.rabbitmq.client.impl.ChannelN.queueDeclare(ChannelN.java:962)
	at com.rabbitmq.client.impl.recovery.AutorecoveringChannel.queueDeclare(AutorecoveringChannel.java:333)
	at com.fly.rabbitmq.consumer.Consumer.main(Consumer.java:37)
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'durable' for queue 'hello' in vhost '/': received 'true' but current is 'false', class-id=50, method-id=10)
	at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:66)
	at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:36)
	at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:502)
	at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:293)
	at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:141)
	... 3 more
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'durable' for queue 'hello' in vhost '/': received 'true' but current is 'false', class-id=50, method-id=10)
	at com.rabbitmq.client.impl.ChannelN.asyncShutdown(ChannelN.java:516)
	at com.rabbitmq.client.impl.ChannelN.processAsync(ChannelN.java:346)
	at com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand(AMQChannel.java:182)
	at com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:114)
	at com.rabbitmq.client.impl.AMQConnection.readFrame(AMQConnection.java:672)
	at com.rabbitmq.client.impl.AMQConnection.access$300(AMQConnection.java:48)
	at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:599)
	at java.lang.Thread.run(Unknown Source)
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值