一、整合
1.引入maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
2.配置rabbit服务器的连接信息
我这里是使用的虚拟机,所以IP是虚拟机IP,host设置为Rabbit服务器所在的IP,记得服务器的机器要设置开放端口(5672)
spring.rabbitmq.host=192.168.56.101
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=123456
二、创建、绑定交换机与队列
分为:
1.设置全局可引用的队列、交换机名称
2.创建交换机(有direct、fanout、topic、header)四种类型
3.创建队列
4.将队列绑定到交换机,并在此时设置绑定的路由、参数
核心语句如下
//创建四种交换机
ExchangeBuilder.directExchange(exchange_name).build();
ExchangeBuilder.fanoutExchange(exchange_name).build();
ExchangeBuilder.topicExchange(exchange_name).build();
ExchangeBuilder.headersExchange(exchange_name).build();
//创建队列
new Queue(queue_name);
//绑定交换机与队列
//没有参数头
BindingBuilder.bind(queue_name).to(exchange_name).with(routing).noargs();
//有参数头
BindingBuilder.bind(queue_name).to(exchange_name).with(routing).and(argMap);
完整代码如下
package org.anna.rabbitmq.config;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class RabbitConfig {
// 队列
// 简单模式
public static final String Queue_HW = "queue_hw";
// 发布订阅模式
public static final String Queue_PB_A = "queue_pb_a";
public static final String Queue_PB_B = "queue_pb_b";
// 工作模式
public static final String Queue_WK_A = "queue_wk_a";
public static final String Queue_WK_B = "queue_wk_b";
// 路由模式
public static final String Queue_RT_A = "queue_rt_a";
public static final String Queue_RT_B = "queue_rt_b";
// topic模式
public static final String Queue_TP_A = "queue_tp_a";
public static final String Queue_TP_B = "queue_tp_b";
// RPC模式
public static final String Queue_RPC_A = "queue_rpc_a";
public static final String Queue_RPC_B = "queue_rpc_b";
// 交换机
public static final String Exchange_HW = "exchange_hw";
public static final String Exchange_PB = "exchange_pb";
public static final String Exchange_WK = "exchange_wk";
public static final String Exchange_RT = "exchange_rt";
public static final String Exchange_TP = "exchange_tp";
public static final String Exchange_RPC = "exchange_rpc";
// 声明交换机
@Bean(Exchange_HW)
public Exchange Exchange_HW() {
return ExchangeBuilder.directExchange(Exchange_HW).build();
}
@Bean(Exchange_PB)
public Exchange Exchange_PB() {
return ExchangeBuilder.fanoutExchange(Exchange_PB).build();
}
@Bean(Exchange_WK)
public Exchange Exchange_WK() {
return ExchangeBuilder.directExchange(Exchange_WK).build();
}
@Bean(Exchange_RT)
public Exchange Exchange_RT() {
return ExchangeBuilder.directExchange(Exchange_RT).build();
}
@Bean(Exchange_TP)
public Exchange Exchange_TP() {
return ExchangeBuilder.topicExchange(Exchange_TP).build();
}
@Bean(Exchange_RPC)
public Exchange Exchange_RPC() {
return ExchangeBuilder.headersExchange(Exchange_RPC).build();
}
// 声明队列
@Bean(RabbitConfig.Queue_HW)
public Queue Queue_HW() {
return new Queue(RabbitConfig.Queue_HW);
}
@Bean(RabbitConfig.Queue_PB_A)
public Queue Queue_PB_A() {
return new Queue(RabbitConfig.Queue_PB_A);
}
@Bean(RabbitConfig.Queue_PB_B)
public Queue Queue_PB_B() {
return new Queue(RabbitConfig.Queue_PB_B);
}
@Bean(RabbitConfig.Queue_WK_A)
public Queue Queue_WK_A() {
return new Queue(RabbitConfig.Queue_WK_A);
}
@Bean(RabbitConfig.Queue_WK_B)
public Queue Queue_WK_B() {
return new Queue(RabbitConfig.Queue_WK_B);
}
@Bean(RabbitConfig.Queue_RT_A)
public Queue Queue_RT_A() {
return new Queue(RabbitConfig.Queue_RT_A);
}
@Bean(RabbitConfig.Queue_RT_B)
public Queue Queue_RT_B() {
return new Queue(RabbitConfig.Queue_RT_B);
}
@Bean(RabbitConfig.Queue_TP_A)
public Queue Queue_TP_A() {
return new Queue(RabbitConfig.Queue_TP_A);
}
@Bean(RabbitConfig.Queue_TP_B)
public Queue Queue_TP_B() {
return new Queue(RabbitConfig.Queue_TP_B);
}
@Bean(RabbitConfig.Queue_RPC_A)
public Queue Queue_RPC_A() {
return new Queue(RabbitConfig.Queue_RPC_A);
}
@Bean(RabbitConfig.Queue_RPC_B)
public Queue Queue_RPC_B() {
return new Queue(RabbitConfig.Queue_RPC_B);
}
// 绑定队列到交换机,并指定路由
@Bean
public Binding Binding_Queue_HW(@Qualifier(RabbitConfig.Queue_HW) Queue queue, @Qualifier(RabbitConfig.Exchange_HW) Exchange exchange) {
// routingKey是绑定的路由
return BindingBuilder.bind(queue).to(exchange).with("").noargs();
}
//workqueue
@Bean
public Binding Binding_Queue_WK_A(@Qualifier(RabbitConfig.Queue_WK_A) Queue queue, @Qualifier(RabbitConfig.Exchange_WK) Exchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("").noargs();
}
@Bean
public Binding Binding_Queue_WK_A_2(@Qualifier(RabbitConfig.Queue_WK_A) Queue queue, @Qualifier(RabbitConfig.Exchange_WK) Exchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("*.1").noargs();
}
@Bean
public Binding Binding_Queue_WK_B(@Qualifier(RabbitConfig.Queue_WK_B) Queue queue, @Qualifier(RabbitConfig.Exchange_WK) Exchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("").noargs();
}
// publish
@Bean
public Binding Binding_Queue_PB_A(@Qualifier(RabbitConfig.Queue_PB_A) Queue queue, @Qualifier(RabbitConfig.Exchange_PB) Exchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("*.1").noargs();
}
@Bean
public Binding Binding_Queue_PB_B(@Qualifier(RabbitConfig.Queue_PB_B) Queue queue, @Qualifier(RabbitConfig.Exchange_PB) Exchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("*.2").noargs();
}
// topic,#匹配多个词,*匹配1个词
@Bean
public Binding Binding_Queue_TP_A(@Qualifier(RabbitConfig.Queue_TP_A) Queue queue, @Qualifier(RabbitConfig.Exchange_TP) Exchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("*.test1").noargs();
}
@Bean
public Binding Binding_Queue_TP_B(@Qualifier(RabbitConfig.Queue_TP_B) Queue queue, @Qualifier(RabbitConfig.Exchange_TP) Exchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("*.test2").noargs();
}
//RPC 参数模式
@Bean
public Binding Binding_Queue_RPC_A(@Qualifier(RabbitConfig.Queue_RPC_A) Queue queue, @Qualifier(RabbitConfig.Exchange_RPC) Exchange exchange) {
Map<String,Object> arg=new HashMap<>();
arg.put("a",1);
return BindingBuilder.bind(queue).to(exchange).with("").and(arg);
}
@Bean
public Binding Binding_Queue_RPC_B(@Qualifier(RabbitConfig.Queue_RPC_B) Queue queue, @Qualifier(RabbitConfig.Exchange_RPC) Exchange exchange) {
Map<String,Object> arg=new HashMap<>();
arg.put("a",2);
return BindingBuilder.bind(queue).to(exchange).with("").and(arg);
}
}
三、四种交换机下的生产者
这里的重点是使用RabbitTemplate ,也有其它方法,需要自己配置host、创建channel等,使用RabbitTemplate 相当于Springboot帮你完成了这些操作,其它方法可以参考RabbitMQ超详细学习笔记(章节清晰+通俗易懂),这是一篇很棒的博客。
RabbitTemplate 有很多种发送、接受方法,大致可以分为send/receive,以及convertAndSend/receiveAndConvert,大致含义为单纯的收发以及转化的收发,均具有多个重载,参考官方说明Class RabbitTemplate
1.direct
- 可以设置路由,交换机可以根据路由进行分发,用于简单模式(HelloWorld)、路由模式(Routing)、工作队列模式(WorkQueues)
- 当多个队列有相同路由时,消息会被分发给这些队列
- 路由可以模糊匹配
import com.rabbitmq.client.Channel;
import org.anna.rabbitmq.config.RabbitConfig;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;
@Component
public class HelloWorld {
@Autowired
RabbitTemplate rabbitTemplate;
public void producer(){
String message="hello world";
rabbitTemplate.convertAndSend(RabbitConfig.Exchange_HW,"",message);
}
@RabbitListener(queues = {RabbitConfig.Queue_HW})
private void comsumer(Object msg, Message message, Channel channel){
System.out.println("HW mode:"+msg);
}
}
2.fanout
- 设置路由不会报错,但路由会失效,统一进行广播分发,用于订阅者模式
代码与direct一样
3.topic
- 可以设置路由,交换机可以根据路由进行分发
- 当多个队列有相同路由时,消息会被分发给这些队列
- 路由可以模糊匹配
代码与direct一样,注意routing即可
4.header
通过匹配header里的参数确定路由,这里发送的是byte,同时使用convertAndSend会报错
public void producer() {
String message1="A";
String message2="B";
MessagePropertiesBuilder builder1=MessagePropertiesBuilder.newInstance();
MessagePropertiesBuilder builder2=MessagePropertiesBuilder.newInstance();
builder1.setHeader("a",1);
builder2.setHeader("a",2);
MessageProperties messageProperties1=builder1.build();
MessageProperties messageProperties2=builder2.build();
Message msg1=new Message(message1.getBytes(),messageProperties1);
Message msg2=new Message(message2.getBytes(),messageProperties2);
rabbitTemplate.send(RabbitConfig.Exchange_RPC,RabbitConfig.Queue_RPC_A,msg1);
rabbitTemplate.send(RabbitConfig.Exchange_RPC,RabbitConfig.Queue_RPC_B,msg2);
}
四、消费者获取信息
1.通过监听获取(立刻获取)
queues里可以是多个队列
@RabbitListener(queues = {RabbitConfig.Queue_HW})
private void comsumer(Object msg, Message message, Channel channel){
System.out.println("HW mode:"+msg);
}
2.通过RabbitTemplate获取(调用时获取)
public void get_from_queue_A(){
Object object=rabbitTemplate.receiveAndConvert(RabbitConfig.Queue_PB_A);
System.out.println("get from A :"+object);
}