pom依赖(生产者消费者相同):
<dependencies>
<!--rabbitmq java客户端-->
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.6.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
1.HelloWorld
生产者:
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 一个生产者对应一个消费者:发送消息
*/
public class Producer_HelloWord {
public static void main(String[] args) throws IOException, TimeoutException {
// 1.创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 2.设置参数
factory.setHost("8.140.49.229"); // 默认localhost
factory.setPort(5672); // 默认5672
factory.setVirtualHost("/"); // 默认/
factory.setUsername("guest"); // 默认guest
factory.setPassword("guest"); // 默认guest
// 3.创建连接Connection
Connection connection = factory.newConnection();
// 4.创建Channel
Channel channel = connection.createChannel();
// 5.创建队列Queue
/*
* queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)
* 1.队列名
* 2.是否持久化,当mq重启之后,是否在
* 3.# 是否独占。只能一个消费者监听队列
* # 当Connection关闭时,是否删除队列
* 4.当没有Consumer时,是否删除队列
* 5.参数
*/
channel.queueDeclare("hello_world", true, false, false, null); // 若队列名称冲突则不创建
// 6.发送消息
/*
* basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
* 1.Exchange名,简单模式交换机使用默认""
* 2.路由名称 (如果是默认Exchange"",必须和队列名相同)
* 3.配置信息
* 4.发送消息数据
*/
String body = "hello rabbitmq~~~";
channel.basicPublish("", "hello_world", null, body.getBytes());
// 7.释放资源
channel.close();
connection.close();
}
}
消费者:
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 接收消息
*/
public class Consumer_HelloWorld {
public static void main(String[] args) throws IOException, TimeoutException {
// 1.创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 2.设置参数
factory.setHost("8.140.49.229"); // 默认localhost
factory.setPort(5672); // 默认5672
factory.setVirtualHost("/"); // 默认/
factory.setUsername("guest"); // 默认guest
factory.setPassword("guest"); // 默认guest
// 3.创建连接Connection
Connection connection = factory.newConnection();
// 4.创建Channel
Channel channel = connection.createChannel();
// 5.接受消息
/*
* basicConsume(String queue, boolean autoAck, Consumer callback)
* 1.队列名
* 2.是否自动确认
* 3.回调对象
*/
Consumer consumer = new DefaultConsumer(channel) {
// 回调方法,当收到消息后自动执行该方法
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) {
System.out.println("consumerTag = " + consumerTag); // 标识
System.out.println("Exchange = " + envelope.getExchange()); // 信息,交换机,路由key
System.out.println("RoutingKey = " + envelope.getRoutingKey());
System.out.println("properties = " + properties); // 配置信息
System.out.println("body: " + new String(body)); // body数据
System.out.println("===============================");
}
};
channel.basicConsume("hello_world", true, consumer);
// 消费者不用释放资源
}
}
2.RabbitMQ工作模式
2.1 Work queues 工作队列模式
工具类:
package com.wsq.utils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class MyConnections {
public Connection connection = null;
public Channel channel = null;
public Channel getChannel() throws IOException, TimeoutException {
// 1.创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 2.设置参数
factory.setHost("8.140.49.229"); // 默认localhost
factory.setPort(5672); // 默认5672
factory.setVirtualHost("/"); // 默认/
factory.setUsername("guest"); // 默认guest
factory.setPassword("guest"); // 默认guest
// 3.创建连接Connection
connection = factory.newConnection();
// 4.创建Channel
channel = connection.createChannel();
return channel;
}
public void closed() throws IOException, TimeoutException {
channel.close();
connection.close();
}
}
生产者:
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.wsq.utils.MyConnections;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 工作队列:发送消息(接收的时候是轮询接收)
*/
public class Producer_b_WorkQueues {
public static void main(String[] args) throws IOException, TimeoutException {
MyConnections myConnections = new MyConnections();
// 4.创建Channel
Channel channel = myConnections.getChannel();
// 5.创建队列Queue
channel.queueDeclare("work_queues", true, false, false, null); // 如何队列名称冲突则不会创建
// 6.发送消息
/*
* basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
* 1.交换机名称,简单模式下交换机用默认的“”
* 2.路由名称 (如果是默认交换机,则必须和队列名称一样)
* 3.配置信息
* 4.发送的消息数据
*/
for (int i = 0; i < 10; i++) {
String body = i + "hello rabbitmq~~~";
channel.basicPublish("", "work_queues", null, body.getBytes());
}
// 7.释放资源
myConnections.closed();
}
}
消费者1:
import com.rabbitmq.client.*;
import com.wsq.utils.MyConnections;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 接收消息
*/
public class Consumer_b_WorkQueues1 {
public static void main(String[] args) throws IOException, TimeoutException {
MyConnections myConnections = new MyConnections();
Channel channel = myConnections.getChannel();
// 5.接受消息
Consumer consumer = new DefaultConsumer(channel) {
// 回调方法,当收到消息后会自动执行该方法
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) {
System.out.println("body: " + new String(body));
}
};
channel.basicConsume("work_queues", true, consumer);
}
}
消费者2:
import com.rabbitmq.client.*;
import com.wsq.utils.MyConnections;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 接收消息
*/
public class Consumer_b_WorkQueues2 {
public static void main(String[] args) throws IOException, TimeoutException {
MyConnections myConnections = new MyConnections();
Channel channel = myConnections.getChannel();
// 6.接受消息
Consumer consumer = new DefaultConsumer(channel) {
// 回调方法,当收到消息后会自动执行该方法
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) {
System.out.println("body: " + new String(body));
}
};
channel.basicConsume("work_queues", true, consumer);
}
}
2.2 Pub/Sub 订阅模式
生产者:
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.wsq.utils.MyConnections;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* FANOUT交换机类型:发送给所以消费者:发送消息
*/
public class Producer_c_PubSub {
public static void main(String[] args) throws IOException, TimeoutException {
MyConnections myConnections = new MyConnections();
// 4.创建Channel
Channel channel = myConnections.getChannel();
// 5.创建交换机Exchange
/*
* exchangeDeclare(String exchange, 交换机名称
* BuiltinExchangeType type, 交换机类型 (DIRECT("direct")定向, FANOUT("fanout")广播, TOPIC("topic")通配符方式)
* boolean durable, 是否持久化
* boolean autoDelete, 是否自动删除
* boolean internal, 内部使用,一般false
* Map<String, Object> arguments) 参数
*/
String exchangeName = "test_fanout";
channel.exchangeDeclare(exchangeName, BuiltinExchangeType.FANOUT, true, false, false, null); // ⭐
// 6.创建队列Queue
String queue1Name = "test_fanout_queue1";
String queue2Name = "test_fanout_queue2";
channel.queueDeclare(queue1Name, true, false, false, null);
channel.queueDeclare(queue2Name, true, false, false, null);
// 7.绑定Exchange、Queue
/*
* queueBind(String queue, String exchange, String routingKey)
* 1.队列名
* 2.交换机名
* 3.路由键,绑定规则
* 若交换机类型为fanout,routingKey为""
*/
channel.queueBind(queue1Name, exchangeName, "");
channel.queueBind(queue2Name, exchangeName, "");
// 8.发送消息
String body = "日志信息:张三调用了findAll方法...日志级别:info...";
channel.basicPublish(exchangeName, "", null, body.getBytes());
// 9.释放资源
myConnections.closed();
}
}
消费者:
import com.rabbitmq.client.*;
import com.wsq.utils.MyConnections;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 消费者1
*/
public class Consumer_c_PubSub1 {
public static void main(String[] args) throws IOException, TimeoutException {
MyConnections myConnections = new MyConnections();
Channel channel = myConnections.getChannel();
String queue1Name = "test_fanout_queue1";
// 5.接受消息
/*
* basicConsume(String queue, boolean autoAck, Consumer callback)
* 1.队列名称
* 2.是否自动确认
* 3.回调对象
*/
Consumer consumer = new DefaultConsumer(channel) {
// 回调方法,当收到消息后会自动执行该方法
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) {
System.out.println("body: " + new String(body));
System.out.println("将日志信息打印到控制台");
}
};
channel.basicConsume(queue1Name, true, consumer);
}
}
import com.rabbitmq.client.*;
import com.wsq.utils.MyConnections;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 消费者2
*/
public class Consumer_c_PubSub2 {
public static void main(String[] args) throws IOException, TimeoutException {
MyConnections myConnections = new MyConnections();
Channel channel = myConnections.getChannel();
String queue2Name = "test_fanout_queue2";
// 5.接受消息
/*
* basicConsume(String queue, boolean autoAck, Consumer callback)
* 1.队列名称
* 2.是否自动确认
* 3.回调对象
*/
Consumer consumer = new DefaultConsumer(channel) {
// 回调方法,当收到消息后会自动执行该方法
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) {
System.out.println("body: " + new String(body));
System.out.println("将日志信息保存数据库");
}
};
channel.basicConsume(queue2Name, true, consumer);
}
}
2.3 Routing 路由模式
生产者:
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.wsq.utils.MyConnections;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* DIRECT交换机类型:只发送给绑定相同的routingkey的消费者:发送消息
*/
public class Producer_d_Routing {
public static void main(String[] args) throws IOException, TimeoutException {
MyConnections myConnections = new MyConnections();
Channel channel = myConnections.getChannel();
// 5.创建交换机
/*
* exchangeDeclare(String exchange, 交换机名称
* BuiltinExchangeType type, 交换机类型 (DIRECT("direct")定向, FANOUT("fanout")广播, TOPIC("topic")通配符方式)
* boolean durable, 是否持久化
* boolean autoDelete, 是否自动删除
* boolean internal, 内部使用,一般false
* Map<String, Object> arguments) 参数
*/
String exchangeName = "test_direct";
channel.exchangeDeclare(exchangeName, BuiltinExchangeType.DIRECT, true, false, false, null); // ⭐
// 6.创建队列
String queue1Name = "test_direct_queue1";
String queue2Name = "test_direct_queue2";
channel.queueDeclare(queue1Name, true, false, false, null);
channel.queueDeclare(queue2Name, true, false, false, null);
// 7.绑定队列和交换机
// 队列1绑定error
channel.queueBind(queue1Name, exchangeName, "error");
// 队列2绑定info error warning
channel.queueBind(queue2Name, exchangeName, "info");
channel.queueBind(queue2Name, exchangeName, "error");
channel.queueBind(queue2Name, exchangeName, "warning");
// 8.发送消息
String body = "日志信息:张三调用了findAll方法...日志级别:info...";
// String body = "日志信息:张三调用了delete方法...日志级别:error...";
channel.basicPublish(exchangeName, "info", null, body.getBytes());
// channel.basicPublish(exchangeName, "error", null, body.getBytes());
// 9.释放资源
myConnections.closed();
}
}
消费者:
import com.rabbitmq.client.*;
import com.wsq.utils.MyConnections;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 接收消息
*/
public class Consumer_d_Routing1 {
public static void main(String[] args) throws IOException, TimeoutException {
MyConnections myConnections = new MyConnections();
Channel channel = myConnections.getChannel();
String queue1Name = "test_direct_queue1";
// 6.接受消息
Consumer consumer = new DefaultConsumer(channel) {
// 回调方法,当收到消息后会自动执行该方法
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) {
System.out.println("body: " + new String(body));
System.out.println("将日志信息保存数据库");
}
};
channel.basicConsume(queue1Name, true, consumer);
}
}
import com.rabbitmq.client.*;
import com.wsq.utils.MyConnections;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 接收消息
*/
public class Consumer_d_Routing2 {
public static void main(String[] args) throws IOException, TimeoutException {
MyConnections myConnections = new MyConnections();
Channel channel = myConnections.getChannel();
String queue2Name = "test_direct_queue2";
// 6.接受消息
Consumer consumer = new DefaultConsumer(channel) {
// 回调方法,当收到消息后会自动执行该方法
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) {
System.out.println("body: " + new String(body));
System.out.println("将日志信息打印到控制台");
}
};
channel.basicConsume(queue2Name, true, consumer);
}
}
2.4 Topics 通配符模式
生产者:
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.wsq.utils.MyConnections;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* TOPIC交换机:通配符绑定消费者:发送消息
*/
public class Producer_e_Topic {
public static void main(String[] args) throws IOException, TimeoutException {
MyConnections myConnections = new MyConnections();
Channel channel = myConnections.getChannel();
// 5.创建交换机
/*
* exchangeDeclare(String exchange, 交换机名称
* BuiltinExchangeType type, 交换机类型 (DIRECT("direct")定向, FANOUT("fanout")广播, TOPIC("topic")通配符方式)
* boolean durable, 是否持久化
* boolean autoDelete, 是否自动删除
* boolean internal, 内部使用,一般false
* Map<String, Object> arguments) 参数
*/
String exchangeName = "test_topic";
channel.exchangeDeclare(exchangeName, BuiltinExchangeType.TOPIC, true, false, false, null); // ⭐
// 6.创建队列
String queue1Name = "test_topic_queue1";
String queue2Name = "test_topic_queue2";
channel.queueDeclare(queue1Name, true, false, false, null);
channel.queueDeclare(queue2Name, true, false, false, null);
// 7.绑定队列和交换机
// routing key 系统的名称。日志的级别
// 需求:所有error级别的日志存入数据库,所以order系统的日志存入数据库
channel.queueBind(queue1Name, exchangeName, "#.error"); // #代表多个单词
channel.queueBind(queue1Name, exchangeName, "order.*"); // *代表一个单词
channel.queueBind(queue2Name, exchangeName, "*.*");
// 8.发送消息
String body = "日志信息:张三调用了findAll方法...日志级别:info...";
// channel.basicPublish(exchangeName, "order.info", null, body.getBytes());
// channel.basicPublish(exchangeName, "goods.info", null, body.getBytes());
channel.basicPublish(exchangeName, "goods.error", null, body.getBytes());
// 9.释放资源
myConnections.closed();
}
}
消费者:
import com.rabbitmq.client.*;
import com.wsq.utils.MyConnections;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 接收消息
*/
public class Consumer_e_Topic1 {
public static void main(String[] args) throws IOException, TimeoutException {
MyConnections myConnections = new MyConnections();
Channel channel = myConnections.getChannel();
String queue1Name = "test_topic_queue1";
// 6.接受消息
Consumer consumer = new DefaultConsumer(channel) {
// 回调方法,当收到消息后会自动执行该方法
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) {
System.out.println("body: " + new String(body));
System.out.println("将日志信息保存数据库");
}
};
channel.basicConsume(queue1Name, true, consumer);
}
}
import com.rabbitmq.client.*;
import com.wsq.utils.MyConnections;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 接收消息
*/
public class Consumer_e_Topic2 {
public static void main(String[] args) throws IOException, TimeoutException {
MyConnections myConnections = new MyConnections();
Channel channel = myConnections.getChannel();
String queue2Name = "test_topic_queue2";
// 6.接受消息
Consumer consumer = new DefaultConsumer(channel) {
// 回调方法,当收到消息后会自动执行该方法
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) {
System.out.println("body: " + new String(body));
System.out.println("将日志信息打印到控制台");
}
};
channel.basicConsume(queue2Name, true, consumer);
}
}