RabbitMQ快速上手以及RabbitMQ交换机的四种模式
创始人
2024-04-18 00:50:55

Win10安装:

​win10下安装 RabbitMQ​_柚几哥哥的博客-CSDN博客

Linux安装:

Linux下载安装 RabbitMQ​_柚几哥哥的博客-CSDN博客

一、基础使用

1、导入依赖

        org.springframework.bootspring-boot-starter-amqporg.springframework.amqpspring-rabbit-testtest

2、配置application.yml

spring:#RabbitMQrabbitmq:#服务器地址host: 192.168.10.100#用户名username: guest#密码password: guest#虚拟主机virtual-host: /#端口port: 5672listener:simple:#消费者最小数量concurrency: 10#消费者最大数量max-concurrency: 10#限制消费者每次只处理一条消息,处理完再继续下一条消息prefetch: 1#启动时是否默认启动容器,默认trueauto-startup: true#被拒绝时重新进入队列default-requeue-rejected: truetemplate:retry:#发布重试,默认falseenabled: true#重试时间 默认1000msinitial-interval: 1000#重试最大次数,默认3次max-attempts: 3#重试最大间隔时间,默认10000msmax-interval: 10000#重试间隔的乘数。比如配2.0 第一次等10s,第二次等20s,第三次等40smultiplier: 1.0

3、编写配置类RabbitMQConfig.java

package com.xxxx.seckill.config;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author zhoubin
* @since 1.0.0
*/
@Configuration
public class RabbitMQConfig {@Beanpublic Queue queue(){return new Queue("queue",true);}
}

4、编写发送者MQSender.java

package com.xxxx.seckill.rabbitmq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author zhoubin
* @since 1.0.0
*/
@Service
@Slf4j
public class MQSender {@Autowiredprivate RabbitTemplate rabbitTemplate;public void send(Object msg) {log.info("发送消息:"+msg);rabbitTemplate.convertAndSend("queue", msg);}
}

5、编写接收者MQReceiver.java

/*** @author zyw* @since 1.0.0*/
@Service
@Slf4j
public class MQReceiver {@RabbitListener(queues = "queue")public void receive(Object msg) {log.info("接受消息:" + msg);}
}

6、编写测试接口UserController.java

/**
* 测试发送RabbitMQ消息
*/
@RequestMapping("/mq")
@ResponseBody
public void mq() {mqSender.send("Hello");
}

7、结果

 二、RabbitMQ交换机

Fanout模式

不处理路由键,只需要简单的将队里绑定到交换机上 发送到交换机的消息都会被转发到与该交换机绑定的所有队列上 Fanout交换机转发消息是最快的

1、RabbitMQConfig.java

package com.xxxx.seckill.config;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author zhoubin
* @since 1.0.0
*/
@Configuration
public class RabbitMQConfig {private static final String QUEUE01 = "queue_fanout01";private static final String QUEUE02 = "queue_fanout02";private static final String EXCHANGE = "fanoutExchange";@Beanpublic Queue queue01(){return new Queue(QUEUE01);}@Beanpublic Queue queue02(){return new Queue(QUEUE02);}@Beanpublic FanoutExchange fanoutExchange(){return new FanoutExchange(EXCHANGE);}@Beanpublic Binding binding01(){return BindingBuilder.bind(queue01()).to(fanoutExchange());}@Beanpublic Binding binding02(){return BindingBuilder.bind(queue02()).to(fanoutExchange());}
}

2、MQSender.java

package com.xxxx.seckill.rabbitmq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author zhoubin
* @since 1.0.0
*/
@Service
@Slf4j
public class MQSender {@Autowiredprivate RabbitTemplate rabbitTemplate;public void send(Object msg) {log.info("发送消息:"+msg);rabbitTemplate.convertAndSend("fanoutExchange","",msg);}
}

3、MQReceiver.java

package com.xxxx.seckill.rabbitmq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
/**
* @author zhoubin
* @since 1.0.0
*/
@Service
@Slf4j
public class MQReceiver {@RabbitListener(queues = "queue_fanout01")public void receive01(Object msg) {log.info("QUEUE01接受消息:" + msg);}@RabbitListener(queues = "queue_fanout02")public void receive02(Object msg) {log.info("QUEUE02接受消息:" + msg);}
}

4、UserController.java

/**
* 测试发送RabbitMQ消息
*/
@RequestMapping("/mq/fanout")
@ResponseBody
public void mq() {mqSender.send("Hello");
}

5、测试

调用 mq/direct01 接口,消息经由交换机转发到绑定该交换机的所有队列

Direct模式

所有发送到Direct Exchange的消息被转发到RouteKey中指定的Queue 注意:Direct模式可以使用RabbitMQ自带的Exchange:default Exchange,所以不需要将 Exchange进行任何绑定(binding)操作,消息传递时,RouteKey必须完全匹配才会被队列接收,否 则该消息会被抛弃。 重点:routing key与队列queues 的key保持一致,即可以路由到对应的queue中。

1、RabbitMQConfig.java

package com.xxxx.seckill.config;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author zhoubin
* @since 1.0.0
*/
@Configuration
public class RabbitMQConfig {private static final String QUEUE01 = "queue_direct01";private static final String QUEUE02 = "queue_direct02";private static final String EXCHANGE = "directExchange";private static final String ROUTINGKEY01 = "queue.red";private static final String ROUTINGKEY02 = "queue.green";@Beanpublic Queue queue01(){return new Queue(QUEUE01);}@Beanpublic Queue queue02(){return new Queue(QUEUE02);}@Beanpublic DirectExchange directExchange(){return new DirectExchange(EXCHANGE);}@Beanpublic Binding binding01(){return
BindingBuilder.bind(queue01()).to(directExchange()).with(ROUTINGKEY01);}@Beanpublic Binding binding02(){return
BindingBuilder.bind(queue02()).to(directExchange()).with(ROUTINGKEY02);}
}

2、MQSender.java

package com.xxxx.seckill.rabbitmq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author zhoubin
* @since 1.0.0
*/
@Service
@Slf4j
public class MQSender {@Autowiredprivate RabbitTemplate rabbitTemplate;public void send01(Object msg) {log.info("发送red消息:"+msg);rabbitTemplate.convertAndSend("directExchange","queue.red",msg);}public void send02(Object msg) {log.info("发送green消息:"+msg);rabbitTemplate.convertAndSend("directExchange","queue.green",msg);}
}

3、MQReceiver.java

package com.xxxx.seckill.rabbitmq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
/**
* @author zhoubin
* @since 1.0.0
*/
@Service
@Slf4j
public class MQReceiver {@RabbitListener(queues = "queue_direct01")public void receive01(Object msg) {log.info("QUEUE01接受消息:" + msg);}@RabbitListener(queues = "queue_direct02")public void receive02(Object msg) {log.info("QUEUE02接受消息:" + msg);}
}

4、UserController.java

/**
* 测试发送RabbitMQ消息
*/
@RequestMapping("/mq/direct01")
@ResponseBody
public void mq01() {mqSender.send01("Hello,Red");
}
/**
* 测试发送RabbitMQ消息
*/
@RequestMapping("/mq/direct02")
@ResponseBody
public void mq02() {mqSender.send02("Hello,Green");
}

5、测试

调用 mq/direct01 接口,消息经由交换机绑定的 queue.red RoutingKey 转发到 queue_direct01 队 列

调用 mq/direct02 接口,消息经由交换机绑定的 queue.green RoutingKey 转发到 queue_direct02 队列

Topic模式

所有发送到Topic Exchange的消息被转发到所有管线RouteKey中指定Topic的Queue上 Exchange将RouteKey和某Topic进行模糊匹配,此时队列需要绑定一个Topic 对于routing key匹配模式定义规则举例如下: routing key为一个句点号 . 分隔的字符串(我们将被句点号 . 分隔开的每一段独立的字符串称为 一个单词),如“stock.usd.nyse”、“nyse.vmw”、“quick.orange.rabbit” routing key中可以存在两种特殊字符 * 与 # ,用于做模糊匹配,其中 * 用于匹配一个单词, # 用 于匹配多个单词(可以是零个)

1、RabbitMQConfig.java

package com.xxxx.seckill.config;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author zhoubin
* @since 1.0.0
*/
@Configuration
public class RabbitMQConfig {private static final String QUEUE01 = "queue_topic01";private static final String QUEUE02 = "queue_topic02";private static final String EXCHANGE = "topicExchange";private static final String ROUTINGKEY01 = "#.queue.#";private static final String ROUTINGKEY02 = "*.queue.#";@Beanpublic Queue queue01(){return new Queue(QUEUE01);}@Beanpublic Queue queue02(){return new Queue(QUEUE02);}@Beanpublic TopicExchange topicExchange(){return new TopicExchange(EXCHANGE);}@Beanpublic Binding binding01(){return
BindingBuilder.bind(queue01()).to(topicExchange()).with(ROUTINGKEY01);}@Beanpublic Binding binding02(){return
BindingBuilder.bind(queue02()).to(topicExchange()).with(ROUTINGKEY02);}
}

2、MQSender.java

package com.xxxx.seckill.rabbitmq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author zhoubin
* @since 1.0.0
*/
@Service
@Slf4j
public class MQSender {@Autowiredprivate RabbitTemplate rabbitTemplate;public void send01(Object msg) {log.info("发送消息(被01队列接受):"+msg);rabbitTemplate.convertAndSend("topicExchange","queue.red.message",msg);}public void send02(Object msg) {log.info("发送消息(被两个queue接受):"+msg);rabbitTemplate.convertAndSend("topicExchange","message.queue.green.abc",msg);}
}

3、MQReceiver.java

package com.xxxx.seckill.rabbitmq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
/**
* @author zhoubin
* @since 1.0.0
*/
@Service
@Slf4j
public class MQReceiver {@RabbitListener(queues = "queue_topic01")public void receive01(Object msg) {log.info("QUEUE01接受消息:" + msg);}@RabbitListener(queues = "queue_topic02")public void receive02(Object msg) {log.info("QUEUE02接受消息:" + msg);}
}

4、UserController.java

/**
* 测试发送RabbitMQ消息
*/
@RequestMapping("/mq/topic01")
@ResponseBody
public void mq01() {mqSender.send01("Hello,Red");
}
/**
* 测试发送RabbitMQ消息
*/
@RequestMapping("/mq/topic02")
@ResponseBody
public void mq02() {mqSender.send02("Hello,Green");
}

5、测试

调用 mq/topic01 接口,消息经由交换机绑定的 #.queue.# RoutingKey 转发到 queue_topic01 队列

调用 mq/topic02 接口,消息经由交换机绑定的 *.queue.# 和 #.queue.# RoutingKey 转发到 queue_topic01 和 queue_topic02 队列

Headers模式

不依赖routingkey,使用发送消息时basicProperties对象中的headers匹配队列 headers是一个键值对类型,键值对的值可以是任何类型 在队列绑定交换机时用x-match来指定,all代表定义的多个键值对都要满足,any则代表只要满足 一个可以了

1、RabbitMQConfig.java

package com.xxxx.seckill.config;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.HeadersExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/**
* @author zhoubin
* @since 1.0.0
*/
@Configuration
public class RabbitMQConfig {private static final String QUEUE01 = "queue_header01";private static final String QUEUE02 = "queue_header02";private static final String EXCHANGE = "headersExchange";@Beanpublic Queue queue01(){return new Queue(QUEUE01);}@Beanpublic Queue queue02(){return new Queue(QUEUE02);}@Beanpublic HeadersExchange headersExchange(){return new HeadersExchange(EXCHANGE);}@Beanpublic Binding binding01(){Map map = new HashMap<>();map.put("color","red");map.put("speed","low");return
BindingBuilder.bind(queue01()).to(headersExchange()).whereAny(map).match();}@Beanpublic Binding binding02(){Map map = new HashMap<>();map.put("color","red");map.put("speed","fast");return
BindingBuilder.bind(queue02()).to(headersExchange()).whereAll(map).match();}
}

2、MQSender.java

package com.xxxx.seckill.rabbitmq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author zhoubin
* @since 1.0.0
*/
@Service
@Slf4j
public class MQSender {@Autowiredprivate RabbitTemplate rabbitTemplate;public void send01(String msg) {log.info("发送消息(被两个queue接受):" + msg);MessageProperties properties = new MessageProperties();properties.setHeader("color", "red");properties.setHeader("speed", "fast");Message message = new Message(msg.getBytes(), properties);rabbitTemplate.convertAndSend("headersExchange", "", message);}public void send02(String msg) {log.info("发送消息(被01队列接受):" + msg);MessageProperties properties = new MessageProperties();properties.setHeader("color", "red");properties.setHeader("speed", "normal");Message message = new Message(msg.getBytes(), properties);rabbitTemplate.convertAndSend("headersExchange", "", message);}
}

3、MQReceiver.java

package com.xxxx.seckill.rabbitmq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
/**
* @author zhoubin
* @since 1.0.0
*/
@Service
@Slf4j
public class MQReceiver {@RabbitListener(queues = "queue_header01")public void receive01(Message message) {log.info("QUEUE01接受Message对象:" + message);log.info("QUEUE01接受消息:" + new String(message.getBody()));}@RabbitListener(queues = "queue_header02")public void receive02(Message message) {log.info("QUEUE02接受Message对象:" + message);log.info("QUEUE02接受消息:" + new String(message.getBody()));}
}

4、UserController.java

/**
* 测试发送RabbitMQ消息
*/
@RequestMapping("/mq/header01")
@ResponseBody
public void mq01() {mqSender.send01("Hello,header01");
}
/**
* 测试发送RabbitMQ消息
*/
@RequestMapping("/mq/header02")
@ResponseBody
public void mq02() {mqSender.send02("Hello,header02");
}

5、测试

queue_header01 设置x-match为any, queue_header02 设置x-match为all。因此调用 mq/header01 接口,可以匹配两个队列

调用 mq/header02 接口,只能匹配 queue_header01 队列

相关内容

热门资讯

应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...