RabbitMQ的项目示例
RabbitMQ简介
MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术。排队指的是应用程序通过 队列来通信。队列的使用除去了接收和发送应用程序同时执行的要求。其中较为成熟的MQ产品有IBM WEBSPHERE MQ。
以下是自己敲的一个小项目,代码复制可用。
创建java项目
创建测试类,导入jar包
示例 1
其中P代表生产者、C表示消费者、中间红色部分代表消息队列
package com.rabbit;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
*
* 类名称:Test01
* 类描述:发送消息
* 创建人:xxx
*
*/
public class Test01 {
public static void main(String[] args) throws IOException, TimeoutException {
//创建链接工厂
ConnectionFactory connFac = new ConnectionFactory() ;
//默认链接的主机名,RabbitMQ-Server安装在本机,所以可以直接用127.0.0.1
connFac.setHost("127.0.0.1");
//创建链接
Connection conn = connFac.newConnection() ;
//创建信息管道
Channel channel = conn.createChannel() ;
// 创建一个名为queue01的队列,防止队列不存在
String queueName = "queue01" ;
//进行信息声明 1.队列名2.是否持久化,3是否局限与链接,4不再使用是否删除,5其他的属性
channel.queueDeclare(queueName, false, false, false, null) ;
String msg = "Hello World!";
//发送消息
// 在RabbitMQ中,消息是不能直接发送到队列,它需要发送到交换器(exchange)中。
// 第一参数空表示使用默认exchange,第二参数表示发送到的queue,第三参数是发送的消息是(字节数组)
channel.basicPublish("", queueName , null , msg.getBytes());
System.out.println("发送 message[" + msg + "] to "+ queueName +" success!");
//关闭管道
channel.close();
//关闭连接
conn.close();
}
}
控制台中显示:
RabbitMQ中显示:
package com.rabbit;
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.ConsumerCancelledException;
import com.rabbitmq.client.QueueingConsumer;
import com.rabbitmq.client.QueueingConsumer.Delivery;
import com.rabbitmq.client.ShutdownSignalException;
/**
*
* 类名称:Test02
* 类描述:接受消息
* 创建人:xxx
*
*/
public class Test02 {
public static void main(String[] args) throws IOException, ShutdownSignalException,
ConsumerCancelledException, InterruptedException, TimeoutException {
// 创建链接工厂
ConnectionFactory connFac = new ConnectionFactory() ;
//默认链接的主机名,RabbitMQ-Server安装在本机,所以可以直接用127.0.0.1
connFac.setHost("127.0.0.1");
//创建链接
Connection conn = connFac.newConnection() ;
//创建信息管道
Channel channel = conn.createChannel() ;
//定义Queue名称
String queueName = "queue01";
//1.队列名2.是否持久化,3是否局限与链接,4不再使用是否删除,5其他的属性
channel.queueDeclare(queueName, false, false, false, null) ;
//上面的部分,与Test01是一样的
//声明一个消费者,配置好获取消息的方式
QueueingConsumer consumer = new QueueingConsumer(channel) ;
channel.basicConsume(queueName, true, consumer) ;
//循环获取消息
while(true){
//循环获取信息
//指向下一个消息,如果没有会一直阻塞
Delivery delivery = consumer.nextDelivery() ;
String msg = new String(delivery.getBody()) ;
System.out.println("接收 message[" + msg + "] from " + queueName);
}
}
}
控制台中显示:
RabbitMQ中显示:
示例 2:
其中P代表生产者、C表示消费者、中间红色部分代表消息队列
注意:先运行消费者1.2.3 然后运行生产者; 生产者会随机均分。
生产者
package com.rabbit3;
import java.io.IOException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.MessageProperties;
/**
*
* 类名称:NewTask
* 类描述:发送者
* 创建人:xxx
*
*/
public class NewTask
{
// 队列名称
private final static String QUEUE_NAME = "workqueue_persistence";
public static void main(String[] args) throws IOException, Exception
{
// 创建连接和频道
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
// 声明队列
boolean durable = true;// 1、设置队列持久化
channel.queueDeclare(QUEUE_NAME, durable, false, false, null);
// (测试)发送条消息,依次在消息后面附加点
for (int i = 5; i > 0; i--)
{
String dots = "";
for (int j = 0; j <= i; j++)
{
dots += ".";
}
String message = "helloworld" + dots + dots.length();
//MessageProperties消息属性 2、设置消息持久化
channel.basicPublish("", QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());
System.out.println(" [x] Sent '" + message + "'");
}
// 关闭频道和资源
channel.close();
connection.close();
}
}
消费者1
package com.rabbit3;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
/**
*
* 类名称:Work1
* 类描述:接收者1
* 创建人:xxx
*
*/
public class Work1
{
// 队列名称
private final static String QUEUE_NAME = "workqueue_persistence";
public static void main(String[] argv) throws java.io.IOException,
java.lang.InterruptedException, Exception
{
System.out.println("接收者1:");
// 区分不同工作进程的输出
int hashCode = Work1.class.hashCode();
// 创建连接和频道
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
// 声明队列
boolean durable = true;
channel.queueDeclare(QUEUE_NAME, durable, false, false, null);
System.out.println(hashCode+ " [*] Waiting for messages.");
//设置最大服务转发消息数量
int prefetchCount = 1;
channel.basicQos(prefetchCount);
QueueingConsumer consumer = new QueueingConsumer(channel);
// 指定消费队列
boolean ack1 = false;
// 打开应答机制
channel.basicConsume(QUEUE_NAME, ack1, consumer);
while (true)
{
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(hashCode + " [x] Received '" + message + "'");
doWork(message);
System.out.println(hashCode + " [x] Done");
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
}
/**
* 每个点耗时1s
*
* 我们使用Thread.sleep来模拟耗时的任务。我们在发送到队列的消息的末尾添加一定数量的点,
* 每个点代表在工作线程中需要耗时1秒,例如hello…将会需要等待3秒。
*/
private static void doWork(String task) throws InterruptedException
{
for (char ch : task.toCharArray())
{
if (ch == '.')
Thread.sleep(1000);
}
}
}
消费者2
package com.rabbit3;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
/**
*
* 类名称:Work2
* 类描述:接收者2
* 创建人:xxx
*
*/
public class Work2
{
// 队列名称
private final static String QUEUE_NAME = "workqueue_persistence";
public static void main(String[] argv) throws java.io.IOException,
java.lang.InterruptedException, Exception
{
System.out.println("接收者2:");
// 区分不同工作进程的输出
int hashCode = Work2.class.hashCode();
// 创建连接和频道
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
// 声明队列
boolean durable = true;
channel.queueDeclare(QUEUE_NAME, durable, false, false, null);
System.out.println(hashCode+ " [*] Waiting for messages.");
//设置最大服务转发消息数量
int prefetchCount = 1;
channel.basicQos(prefetchCount);
QueueingConsumer consumer = new QueueingConsumer(channel);
// 指定消费队列
boolean ack2 = false;
// 打开应答机制
channel.basicConsume(QUEUE_NAME, ack2, consumer);
while (true)
{
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(hashCode + " [x] Received '" + message + "'");
doWork(message);
System.out.println(hashCode + " [x] Done");
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
}
/**
* 每个点耗时1s
*
* 我们使用Thread.sleep来模拟耗时的任务。我们在发送到队列的消息的末尾添加一定数量的点,
* 每个点代表在工作线程中需要耗时1秒,例如hello…将会需要等待3秒。
*/
private static void doWork(String task) throws InterruptedException
{
for (char ch : task.toCharArray())
{
if (ch == '.')
Thread.sleep(1000);
}
}
}
消费者3
package com.rabbit3;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
/**
*
* 类名称:Work3
* 类描述:接收者3
* 创建人:xxx
*
*/
public class Work3
{
// 队列名称
private final static String QUEUE_NAME = "workqueue_persistence";
public static void main(String[] argv) throws java.io.IOException,
java.lang.InterruptedException, Exception
{
System.out.println("接收者3:");
// 区分不同工作进程的输出
int hashCode = Work3.class.hashCode();
// 创建连接和频道
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
// 声明队列
boolean durable = true;
channel.queueDeclare(QUEUE_NAME, durable, false, false, null);
System.out.println(hashCode+ " [*] Waiting for messages.");
//设置最大服务转发消息数量
int prefetchCount = 1;
channel.basicQos(prefetchCount);
QueueingConsumer consumer = new QueueingConsumer(channel);
// 指定消费队列
boolean ack3 = false;
// 打开应答机制
channel.basicConsume(QUEUE_NAME, ack3, consumer);
while (true)
{
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(hashCode + " [x] Received '" + message + "'");
doWork(message);
System.out.println(hashCode + " [x] Done");
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
}
/**
* 每个点耗时1s
*
* 我们使用Thread.sleep来模拟耗时的任务。我们在发送到队列的消息的末尾添加一定数量的点,
* 每个点代表在工作线程中需要耗时1秒,例如hello…将会需要等待3秒。
*/
private static void doWork(String task) throws InterruptedException
{
for (char ch : task.toCharArray())
{
if (ch == '.')
Thread.sleep(1000);
}
}
}
结果
控制台中显示: