pom.xml(虽然有几种模式,但是pom.xml内容不变)
<?xml version="1.0" encoding="UTF-8"?>
<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>cn.it.source</groupId>
<artifactId>day078_rabbitmq_demo</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.rabbitmq/amqp-client -->
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<!--和springboot2.0.5对应-->
<version>5.4.1</version>
</dependency>
</dependencies>
</project>
fanout模式
消费者1
package cn.itjim._01_hello._03_fanout;
import cn.itjim._01_hello.util.ConnectionUtil;
import com.rabbitmq.client.*;
import java.io.IOException;
/**
* 1.创建队列
* 2.队列绑定到交换机
* 3.每个消费者要监听自己的队列
*/
public class Consumers1 {
public static final String FANOUT_QUEUE1="FANOUT_QUEUE1";
public static void main(String[] args) throws Exception {
//创建连接
Connection connection = ConnectionUtil.getConnection();
//创建通道
Channel channel = connection.createChannel();
//同时处理的消息数量
channel.basicQos(1);
//创建队列
channel.queueDeclare(FANOUT_QUEUE1,true,false, false, null);
//队列绑定交换机
//参数一:队列名,参数二:交换机名字,参数三:routingkey
channel.queueBind(FANOUT_QUEUE1,Sender.FANOUT_EXCHANGE,"");
//回调,重写回调方法,消费消息
Consumer con = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("body"+new String(body));
System.out.println("consumerTag="+consumerTag);
System.out.println("envelope="+envelope);
System.out.println("properties="+properties);
//System.out.println(1/0);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("========================");
//在所有业务说做完之后,手动签收
channel.basicAck(envelope.getDeliveryTag(), false);//参数一: ,参数二:是否签收多个,false
}
};
//监听队列
//参数二:是否自动签收
channel.basicConsume(FANOUT_QUEUE1,false,con );
/*
*签收不能与消费相等
*
* 注意:在自动签收开启,并且在回调函数里面有错误的时候,会造成消息丢失
* 所以不能自动签收,需要手动签收
* */
}
}
消费者2
package cn.itjim._01_hello._03_fanout;
import cn.itjim._01_hello.util.ConnectionUtil;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.nio.file.FileSystemLoopException;
public class Consumer2 {
//声明队列的名字
private static final String FANOUT_QUEUE2 = "fanout_queue2";
public static void main(String[] args) throws Exception {
//创建连接
Connection connection = ConnectionUtil.getConnection();
//创建通道
Channel channel = connection.createChannel();
//同时处理消息的数量
channel.basicQos(1);
//创建队列
channel.queueDeclare(FANOUT_QUEUE2, true, false, false, null);
//队列和交换机绑定
channel.queueBind(FANOUT_QUEUE2, Sender.FANOUT_EXCHANGE, "");
//匿名内部类,重写回调方法;手动接收消息
Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("body="+body);
channel.basicAck(envelope.getDeliveryTag(), false);
}
};
//监听队列
channel.basicConsume(FANOUT_QUEUE2, false, consumer);
}
}
生产者
package cn.itjim._01_hello._03_fanout;
import cn.itjim._01_hello.util.ConnectionUtil;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
/**
* 多个消费者都可以收到的模式
* 1.不创建队列
* 2.创建交换机
* 3.给交换机发送消息
*/
public class Sender {
//给交换机起名字
public static final String FANOUT_EXCHANGE = "FANOUT_EXCHANGE";
public static void main(String[] args) throws Exception {
//创建连接
Connection connection = ConnectionUtil.getConnection();
//创建通道
Channel channel = connection.createChannel();
//创建交换机,参数一:交换机名字,参数二:交换机类型,参数三:是否持久化
channel.exchangeDeclare(FANOUT_EXCHANGE, BuiltinExchangeType.FANOUT, true);
//定义发送的内容
String str = "在干嘛?";
//发送消息
//方法参数一:交换机的名字,使用默认的交换机就写空字符串,参数二:队列的名字routing key,参数三:其他属性,参数四:发送的内容
channel.basicPublish(FANOUT_EXCHANGE, "", null,str.getBytes() );
//关闭连接
channel.close();
connection.close();
}
}
运行顺序,先开启生产者再开启消费者(下同)
direct模式
消费者1
package cn.itjim._01_hello._04_direct;
import cn.itjim._01_hello.util.ConnectionUtil;
import com.rabbitmq.client.*;
import java.io.IOException;
//消费类1
public class Consumer1 {
private static final String DIRECT_QUEUE1 = "direct_queue1";
public static void main(String[] args) throws Exception {
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
channel.basicQos(1);
channel.queueDeclare(DIRECT_QUEUE1, true, false, false, null);
channel.queueBind(DIRECT_QUEUE1, Sender.DIRECT_EXCHANGE, "order");
Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println(body);
//手动消费
channel.basicAck(envelope.getDeliveryTag(), false);
}
};
channel.basicConsume(DIRECT_QUEUE1, false, consumer);
}
}
消费者2
package cn.itjim._01_hello._04_direct;
import cn.itjim._01_hello.util.ConnectionUtil;
import com.rabbitmq.client.*;
import java.io.IOException;
//消费类2
public class Consumer2 {
private static final String DIRECT_QUEUE2 ="direct_queue2";
public static void main(String[] args) throws Exception {
//创建连接
Connection connection = ConnectionUtil.getConnection();
//创建通道
Channel channel = connection.createChannel();
//每次处理消息数量
channel.basicQos(1);
channel.queueDeclare(DIRECT_QUEUE2, true, false, false, null);
//队列和交换机绑定
channel.queueBind(DIRECT_QUEUE2, Sender.DIRECT_EXCHANGE, "pay");
//回调方法
Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("body="+body);
//手动签收
channel.basicAck(envelope.getDeliveryTag(), false);
}
};
//监听队列
channel.basicConsume(DIRECT_QUEUE2, false, consumer);
}
}
生产者
package cn.itjim._01_hello._04_direct;
import cn.itjim._01_hello.util.ConnectionUtil;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
/**direct模型,指定由谁来消费消息
* 1.在创建交换机的时候,指定类型为direct
* 2.在发送消息的时候通过routingkey来指定由谁来接收消息
*
*/
public class Sender {
public static final String DIRECT_EXCHANGE = "DIRECT_EXCHANGE";
public static void main(String[] args) throws Exception {
//创建连接
Connection connection = ConnectionUtil.getConnection();
//创建通道
Channel channel = connection.createChannel();
//创建交换机,参数一:交换机名字,参数二:交换机类型,参数三:是否持久化
channel.exchangeDeclare(DIRECT_EXCHANGE, BuiltinExchangeType.DIRECT, true);
//创建队列
//方法参数一:队列的名字,参数二:是否持久化,参数三:是否独占,参数四:是否用完即删,参数五:其他属性,没有属性就写null
// channel.queueDeclare(FANOUT_EXCHANGE, true, false, false, null);
//定义发送的内容
String str = "在干嘛?";
//发送消息
//方法参数一:交换机的名字,使用默认的交换机就写空字符串,参数二:队列的名字key,参数三:其他属性,参数四:发送的内容
//参数二指定那个队列接收,就是那个队列接收
channel.basicPublish(DIRECT_EXCHANGE, "order", null,str.getBytes() );//参数一:;参数二:
//关闭连接
channel.close();
connection.close();
}
}
topics模式
消费者1
package cn.itjim._01_hello._05_topics;
import cn.itjim._01_hello.util.ConnectionUtil;
import com.rabbitmq.client.*;
import java.io.IOException;
public class Consumer1 {
private static final String TOPICS_QUEUE1 = "TOPICS_QUEUE1";
public static void main(String[] args) throws Exception {
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
channel.basicQos(1);
channel.queueDeclare(TOPICS_QUEUE1, true, false, false, null);
channel.queueBind(TOPICS_QUEUE1, Sender.TOPICS_EXCHANGE, "order.*");
Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("=============");
channel.basicAck(envelope.getDeliveryTag(), false);
}
};
channel.basicConsume(TOPICS_QUEUE1, false, consumer);
}
}
消费者2
package cn.itjim._01_hello._05_topics;
import cn.itjim._01_hello.util.ConnectionUtil;
import com.rabbitmq.client.*;
import java.io.IOException;
public class Consumer2 {
private static final String TOPICS_QUEUE2 = "TOPICS_QUEUE2";
public static void main(String[] args) throws Exception {
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
channel.basicQos(1);
channel.queueDeclare(TOPICS_QUEUE2, true, false, false, null);
channel.queueBind(TOPICS_QUEUE2, Sender.TOPICS_EXCHANGE, "adopt.*");
Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("=============");
channel.basicAck(envelope.getDeliveryTag(), false);
}
};
channel.basicConsume(TOPICS_QUEUE2, false, consumer);
}
}
生产者
package cn.itjim._01_hello._05_topics;
import cn.itjim._01_hello.util.ConnectionUtil;
import com.rabbitmq.client.*;
import java.io.IOException;
/**
*
*/
public class Sender {
public static final String TOPICS_EXCHANGE = "topics_exchange";
public static void main(String[] args) throws Exception {
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(TOPICS_EXCHANGE, BuiltinExchangeType.TOPIC, true);
String str = "heheheh";
channel.basicPublish(TOPICS_EXCHANGE, "order.add", null, str.getBytes());
channel.close();
connection.close();
}
}
workqueue模式
消费者1
package cn.itjim._01_hello._o2_workqueue;
import cn.itjim._01_hello.util.ConnectionUtil;
import com.rabbitmq.client.*;
import java.io.IOException;
public class Consumers1 {
public static void main(String[] args) throws Exception {
//创建连接
Connection connection = ConnectionUtil.getConnection();
//创建通道
Channel channel = connection.createChannel();
//同时处理的消息数量
channel.basicQos(1);
//回调,重写回调方法,消费消息
Consumer con = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("body"+new String(body));
System.out.println("consumerTag="+consumerTag);
System.out.println("envelope="+envelope);
System.out.println("properties="+properties);
//System.out.println(1/0);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("========================");
//在所有业务说做完之后,手动签收
channel.basicAck(envelope.getDeliveryTag(), false);//参数一: ,参数二:是否签收多个,false
}
};
//监听队列
//参数二:是否自动签收
channel.basicConsume(Sender.WORK_QUEUE,false,con );
/*
*签收不能与消费相等
*
* 注意:在自动签收开启,并且在回调函数里面有错误的时候,会造成消息丢失
* 所以不能自动签收,需要手动签收
* */
}
}
消费者2
package cn.itjim._01_hello._o2_workqueue;
import cn.itjim._01_hello.util.ConnectionUtil;
import com.rabbitmq.client.*;
import java.io.IOException;
public class Consumers2 {
public static void main(String[] args) throws Exception {
//创建连接
Connection connection = ConnectionUtil.getConnection();
//创建通道
Channel channel = connection.createChannel();
//同时处理的消息数量
channel.basicQos(1);
//回调,重写回调方法,消费消息
Consumer con = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("body"+new String(body));
System.out.println("consumerTag="+consumerTag);
System.out.println("envelope="+envelope);
System.out.println("properties="+properties);
//System.out.println(1/0);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("========================");
//在所有业务说做完之后,手动签收
channel.basicAck(envelope.getDeliveryTag(), false);//参数一: ,参数二:是否签收多个,false
}
};
//监听队列
//参数二:是否自动签收
channel.basicConsume(Sender.WORK_QUEUE,false,con );
/*
*签收不能与消费相等
*
* 注意:在自动签收开启,并且在回调函数里面有错误的时候,会造成消息丢失
* 所以不能自动签收,需要手动签收
* */
}
}
生产者
package cn.itjim._01_hello._o2_workqueue;
import cn.itjim._01_hello.util.ConnectionUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
/**
* 一个生产者,多个消费者
* 多个消费者监听同一个队列,消费者轮流执行消费,
* 在消费者里面配置每次处理的消息数量: channel.basicQos(1);就是能者多劳模式
*/
public class Sender {
public static final String WORK_QUEUE = "WORK_QUEUE";
public static void main(String[] args) throws Exception {
//创建连接
Connection connection = ConnectionUtil.getConnection();
//创建通道
Channel channel = connection.createChannel();
//创建交换机,这里使用默认的交换机,并没有创建
//创建队列
//方法参数一:队列的名字,参数二:是否持久化,参数三:是否独占,参数四:是否用完即删,参数五:其他属性,没有属性就写null
channel.queueDeclare(WORK_QUEUE, true, false, false, null);
//定义发送的内容
String str = "在干嘛?";
//发送消息
//方法参数一:交换机的名字,使用默认的交换机就写空字符串,参数二:队列的名字key,参数三:其他属性,参数四:发送的内容
channel.basicPublish("", "WORK_QUEUE", null,str.getBytes() );//参数一:;参数二:
//关闭连接
channel.close();
connection.close();
}
}
统一工具类
package cn.itjim._01_hello.util;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class ConnectionUtil {
/**
* 建立与RabbitMQ的连接
* @return
* @throws Exception
*/
public static Connection getConnection() throws Exception {
//定义连接工厂
ConnectionFactory factory = new ConnectionFactory();
//设置服务地址
factory.setHost("127.0.0.1");
//端口
factory.setPort(5672);
//设置账号信息,用户名、密码、vhost
factory.setVirtualHost("/");
factory.setUsername("账号");
factory.setPassword("密码");
// 通过工程获取连接
Connection connection = factory.newConnection();
return connection;
}
}
附带网页访问地址:http://localhost:15672/#/queues