RabbitMQ指令
# 服务启动相关
systemctl start|restart|stop|status rabbitmq-server
# 管理命令行,用来不使用web管理界面情况下命令操作RabbitMQ
rabbitmqctl help #可以查看更多命令
# 插件管理命令行
rabbitmq-plugins enable|list|disable
# disable 禁用 enable 启用
RabbitMQ生产和消费消息
第一种模型(直连)
一个生产者对应一个消费者
RabbitMQ生产消息
// 创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("8.142.28.95");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/ems");
connectionFactory.setUsername("wupan");
connectionFactory.setPassword("wupan");
// 获取连接对象
Connection connection = connectionFactory.newConnection();
// 获取连接通道
Channel channel = connection.createChannel();
// 通道和队列要绑定
// 参数1:队列名称,不存在自动创建
// 参数2:用来定义队列特性是否要持久化,true 持久化队列,false:不持久化
// 参数3:是否独占队列 true 独占队列;false:不独占
// 参数4 是否在消费完成自动删除队列;true:自动删除;false 不自动删除
// 参数5:额外附件参数
channel.queueDeclare("newhello",true,false,false,null);
// 参数1: 交换机名称
// 参数2:队列名称
// 参数3:传递消息额外设置
// 参数4:消息的具体内容
channel.basicPublish("","newhello",MessageProperties.PERSISTENT_TEXT_PLAIN,"服务重启,消息是否丢失".getBytes());
// 关闭通道
channel.close();
// 关闭连接
connection.close();
RabbitMQ消费消息
// 创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("8.142.28.95");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/ems");
connectionFactory.setUsername("wupan");
connectionFactory.setPassword("wupan");
// 获取连接对象
Connection connection = connectionFactory.newConnection();
// 获取连接通道
Channel channel = connection.createChannel();
// 通道绑定队列
// * 消费消息队列要和生产消息队列参数保持一致
channel.queueDeclare("newhello",true,false,false,null);
// 消费消息
// 参数1:消费队列名称
// 参数2:开启消息的自动确认机制
// 参数3:消费消息时,回调接口
channel.basicConsume("newhello", true, new DefaultConsumer(channel){
@Override // 参数1:标签
// 参数2 : 信封
// 参数4:消息队列中取出的消息
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("new String(body)=" + new String(body));
}
});
第二种模型(work queue)
默认情况下,work queue消费者消费消息时,进行循环消费
生产消息
// 获取连接
Connection connection = RabbitMQUtils.getConnection();
// 获取通道
Channel channel = connection.createChannel();
// 通过通道声明队列
channel.queueDeclare("work",true,false,false,null);
// 生产消息
for (int i = 0; i < 10; i++) {
channel.basicPublish("","work",null,(i + "hello work queue").getBytes());
}
RabbitMQUtils.closeConnectionAndChanel(channel,connection);
消费消息
// 消费者1
Connection connection = RabbitMQUtils.getConnection();
Channel channel = connection.createChannel();
channel.queueDeclare("work",true,false,false,null);
channel.basicConsume("work",true,new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("消费者-1:" + new String(body));
}
});
// 消费者2
Connection connection = RabbitMQUtils.getConnection();
Channel channel = connection.createChannel();
channel.queueDeclare("work",true,false,false,null);
channel.basicConsume("work",true,new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("消费者-1:" + new String(body));
}
});
消息确认机制,能者多劳,保证消息的消费的原子性和正确性
Connection connection = RabbitMQUtils.getConnection();
Channel channel = connection.createChannel();
channel.queueDeclare("work",true,false,false,null);
// 每次通道中只能放入一条消息
channel.basicQos(1);
// 参数2:true:自动确认;false:手动确认
channel.basicConsume("work",false,new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("消费者-1:" + new String(body));
// 参数1:队列中消息的标识;参数2:true:批量确认;false:单个确认
channel.basicAck(envelope.getDeliveryTag(),false);
}
});
第三种模型(fanout)
生产消息
fanout类型,直接发送消息给交换机
// 获取连接
Connection connection = RabbitMQUtils.getConnection();
Channel channel = connection.createChannel();
// 将通道申明指定的交换机
// 参数1: 交换机名称;参数2:交换机类型 fanout:广播类型
channel.exchangeDeclare("logs","fanout");
// 发送消息
channel.basicPublish("logs","",null,"fanout type message111".getBytes());
RabbitMQUtils.closeConnectionAndChanel(channel,connection);
消费消息
绑定交换机,创建临时队列,然后再通道中绑定交换机和队列,再从队列中取出消息
// 获取连接
Connection connection = RabbitMQUtils.getConnection();
// 获取通道对象
Channel channel = connection.createChannel();
// 通道绑定交换机
channel.exchangeDeclare("logs","fanout");
//临时队列
String queue = channel.queueDeclare().getQueue();
// 绑定交换机和队列
channel.queueBind(queue,"logs","");
channel.basicConsume(queue,true,new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("消费者1:" + new String(body));
}
});
第四种模型(drict)
生产者发送消息时,将交换机和路由key进行绑定,消费者消费消息时,要满足对应的key才能消费
第五种模型(topic)
生产者发送消息时,将交换机和路由key进行绑定,消费者消费消息时,可以通过动态路由key的方式进行消费
路由key必须是 user.add 的形式
消费者可以通过 user.* or user.# 的动态路由key进行消费
user.* 只能匹配 user.add,表示只能匹配一个单词
user.# 可以匹配 user,user.add,user.add.success等等,后面可以一直拼接,表示可以匹配0个或者多个单词
SpringBoot整合RabbitMQ模型
helloWorld模型
生产者
package com.example.demo;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@SpringBootTest(classes = DemoApplication.class)
@RunWith(SpringRunner.class)
class DemoApplicationTests {
// 注入rabbitTemplate
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void test () {
// convertAndSend 发送消息
// 参数1:队列名称;参数2: 消息内容
rabbitTemplate.convertAndSend("hello_test","hello world");
}
}
消费者
package com.example.demo;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class HelloCustomer {
// RabbitListener监听队列名称:【hello_test】
// RabbitListener可以注释在类上,也可以注释在方法上
@RabbitListener(queuesToDeclare = @Queue("hello_test"))
// RabbitHandler声明回调方法,方法名可以是任意的
@RabbitHandler
public void receiver (String message) {
System.out.println("message = " + message);
}
}
工作队列模型
生产者
package com.example.demo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@SpringBootTest(classes = DemoApplication.class)
@RunWith(SpringRunner.class)
public class DemoApplicationTests {
// 注入rabbitTemplate
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void testWork () {
rabbitTemplate.convertAndSend("word","work模型");
}
}
消费者
package com.example.demo.work;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class WorkConsumer {
// 一个消费者
@RabbitListener(queuesToDeclare = @Queue("work"))
public void receiver1 (String message){
System.out.println("message1 = " + message);
}
// 一个消费者
@RabbitListener(queuesToDeclare = @Queue("work"))
public void receiver2 (String message){
System.out.println("message2 = " + message);
}
}
Fanout广播模式
生产者
package com.example.demo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@SpringBootTest(classes = DemoApplication.class)
@RunWith(SpringRunner.class)
public class DemoApplicationTests {
// 注入rabbitTemplate
@Autowired
private RabbitTemplate rabbitTemplate;
// fanout
@Test
public void testFanout() {
rabbitTemplate.convertAndSend("exchange_logs","","springboot整合rabbitmq,发送fanout消息");
}
}
消费者
package com.example.demo.fanout;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class HelloFanout {
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue,// 不指定名称,表示生成临时队列
exchange = @Exchange(value = "exchange_logs", type = "fanout") // value 交换机名称,type:发送消息类型
)
})
public void receiver1(String message) {
System.out.println("message1:" + message);
}
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue,// 不指定名称,表示生成临时队列
exchange = @Exchange(value = "exchange_logs", type = "fanout") // value 交换机名称,type:发送消息类型
)
})
public void receiver2(String message) {
System.out.println("message2:" + message);
}
}
Router路由模式
生产者
package com.example.demo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@SpringBootTest(classes = DemoApplication.class)
@RunWith(SpringRunner.class)
public class DemoApplicationTests {
// 注入rabbitTemplate
@Autowired
private RabbitTemplate rabbitTemplate;
// router
@Test
public void testRouter () {
rabbitTemplate.convertAndSend("router_los","info","springboot整合rabbitmq,发送router消息【info】");
rabbitTemplate.convertAndSend("router_los","error","springboot整合rabbitmq,发送router消息【error】");
}
}
消费者
package com.example.demo.router;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class HelloRouter {
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue,
exchange = @Exchange(value = "router_los", type = "direct"),
// key可以指定要生产者发送要的对应的key的消息
key = {"info","warn","debugger"}
)
})
public void receiver1 (String message) {
System.out.println("message1:" + message);
}
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue, // 不指定队列名称,表示生成临时队列
exchange = @Exchange(value = "router_los", type = "direct"),
key = {"error"}
)
})
public void receiver2 (String message) {
System.out.println("message2:" + message);
}
}
Topic模式(动态路由)模式
生产者
package com.example.demo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@SpringBootTest(classes = DemoApplication.class)
@RunWith(SpringRunner.class)
public class DemoApplicationTests {
// 注入rabbitTemplate
@Autowired
private RabbitTemplate rabbitTemplate;
// topic
@Test
public void testTopic () {
rabbitTemplate.convertAndSend("topic_logs","user.add.save","springboot整合rabbitmq,发送topic消息【user.add.save】");
}
}
消费者
package com.example.demo.topic;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class HelloTopic {
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue,
exchange = @Exchange(value = "topic_logs", type = "topic"),
// #可以匹配多个
key = {"user.#"}
)
})
public void receiver1 (String message) {
System.out.println("message1:" + message);
}
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue,
exchange = @Exchange(value = "topic_logs", type = "topic"),
// * 只能匹配到一个
key = {"user.*"}
)
})
public void receiver2 (String message) {
System.out.println("message2:" + message);
}
}