文章目录
前言
简单的快速入门RabbitMQ,并且实现死信队列。
一、RabbitMQ使用Docker容器搭建。
查询docker容器中的RabbitMQ镜像。(建议下载第二个,第一个本人始终没有下载成功,哈哈)
docker search rabbitmq
拉去镜像信息,等待拉去成功,成功后会看到有一串非常长的加密后的id。
docker pull docker.io/bitnami/rabbitmq
接下来通过docker命令启动镜像,并且需要给RabbitMQ设置账号密码,版本问题,废弃了之前的guest用户。(切记哦)
docker run -d --hostname rabbit-host --name rabbitmq -e RABBITMQ_DEFAULT_USER=root -e RABBITMQ_DEFAULT_PASS=123456 -p 15672:15672 -p 5672:5672 docker.io/bitnami/rabbitmq
启动成功后,输入下面命令查看是否运行成功。
docker ps
二、死信队列使用步骤
1.引入库
代码如下(示例):
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>2.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-amqp</artifactId>
<version>2.1.6.RELEASE</version>
</dependency>
2.yml文件配置
##端口号
server.port=8083
##rabbitmq
spring.rabbitmq.host=192.168.231.128
spring.rabbitmq.port=5672
spring.rabbitmq.username=root
spring.rabbitmq.password=123456
3.添加RabbitMQ的配置文件
创建普通队列和死信队列,普通队列消息过期后会将消息通过交换机转发到死信队列中。
package com.hh.rabbitmq.config;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class RabbitConfig {
@Bean
public Queue ttlQueue() {
Map<String, Object> args = new HashMap<>();
args.put("x-dead-letter-exchange","spring.direct.deadExchange");
args.put("x-dead-letter-routing-key","spring.deadRouting");
// args.put("x-message-ttl",10000); // 设置消息过期时间无效果
// args.put("x-expires",10000); // 设置队列过期时间无效果
return new Queue("spring.direct.ttl.queue",true,false,false,args);
}
@Bean
public Queue deadQueue() {
return new Queue("spring.direct.deadQueue");
}
@Bean
public DirectExchange directExchange() {
return new DirectExchange("spring.direct.exchange");
}
@Bean
public DirectExchange deadDirectExchange() {
return new DirectExchange("spring.direct.deadExchange");
}
@Bean
public Binding queueBinding1() {
return BindingBuilder.bind(ttlQueue()).to(directExchange()).with("spring.routing");
}
@Bean
public Binding queueBinding2() {
return BindingBuilder.bind(deadQueue()).to(deadDirectExchange()).with("spring.deadRouting");
}
}
4.消息接收
package com.hh.rabbitmq.config;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class ReceiverMessage {
@RabbitListener(queues = "spring.direct.deadQueue")
@RabbitHandler
public void getMessage(String message) {
System.out.println(message);
}
}
5.消息投放
package com.hh.rabbitmq.controller;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class RabbitController {
@Autowired
private AmqpTemplate amqpTemplate;
@RequestMapping(value = "sendMessage",method = RequestMethod.POST)
public String sendMessage(@RequestBody String message) {
try {
amqpTemplate.convertAndSend("spring.direct.exchange", "spring.routing", message, new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
message.getMessageProperties().setExpiration("10000"); // 设置消息过期时间,过期后,由于配置config配置了当前队列会将过期的消息转发到死性队列中。
return message;
}
});
} catch (Exception e) {
e.printStackTrace();
}
return "ok";
}
}
3.Fanout模式案例
1.配置队列和交换机绑定关系
package com.hh.rabbitmq.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;
@Configuration
public class FanoutRabbitConfig {
@Bean
public Queue fanoutQueue1() {
return new Queue("spring.fanout.queue1");
}
@Bean
public Queue fanoutQueue2() {
return new Queue("spring.fanout.queue2");
}
@Bean
public FanoutExchange fanoutExchange() {
return new FanoutExchange("spring.fanout.exchange");
}
@Bean
public Binding bing1() {
return BindingBuilder.bind(fanoutQueue1()).to(fanoutExchange());
}
@Bean
public Binding bing2() {
return BindingBuilder.bind(fanoutQueue2()).to(fanoutExchange());
}
}
2.接口测试
package com.hh.rabbitmq.controller;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Random;
@RestController
public class RabbitController {
@Autowired
private AmqpTemplate amqpTemplate;
@RequestMapping(value = "sendFanoutMessage",method = RequestMethod.POST)
public String sendFanoutMessage(@RequestBody String message) {
try {
amqpTemplate.convertAndSend("spring.fanout.exchange", "", message, new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
// message.getMessageProperties().setExpiration("10000"); // 设置消息过期时间,过期后,由于配置config配置了当前队列会将过期的消息转发到死性队列中。
return message;
}
});
} catch (Exception e) {
e.printStackTrace();
}
return "ok";
}
}
3.消费者监听队列进行消费
package com.hh.rabbitmq.config;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class ReceiverMessage {
@RabbitListener(queues = "spring.fanout.queue1")
@RabbitHandler
public void getFanoutQueue1(String message) {
System.out.println(message);
}
}
4.Topic模式案例
1.配置队列和交换机绑定关系
package com.hh.rabbitmq.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;
@Configuration
public class TopicRabbitConfig {
@Bean
public Queue topicQueue1() {
return new Queue("spring.topic.queue1");
}
@Bean
public Queue topicQueue2() {
return new Queue("spring.topic.queue2");
}
@Bean
public TopicExchange topicExchange() {
return new TopicExchange("spring.topic.exchange");
}
@Bean
public Binding binding1() {
return BindingBuilder.bind(topicQueue1()).to(topicExchange()).with("com.hh.#"); // 路由匹配规则
}
@Bean
public Binding binding2() {
return BindingBuilder.bind(topicQueue2()).to(topicExchange()).with("#.organization"); // 路由匹配规则
}
}
路由匹配规则:# 表示配置(0至多个),* 表示配置(只能接一个)
2.接口测试
package com.hh.rabbitmq.controller;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Random;
@RestController
public class RabbitController {
@Autowired
private AmqpTemplate amqpTemplate;
@RequestMapping(value = "sendTopicMessage",method = RequestMethod.POST)
public String sendTopicMessage(@RequestBody String message) {
try {
amqpTemplate.convertAndSend("spring.topic.exchange","com.hh.organization",message);
} catch (Exception e) {
e.printStackTrace();
}
return "ok";
}
}
3.消费者监听队列进行消费
package com.hh.rabbitmq.config;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class ReceiverMessage {
@RabbitListener(queues = "spring.topic.queue1")
@RabbitHandler
public void getTopicQueue1(String message) {
System.out.println(message);
}
}
5.Headers模式案例
1.配置队列和交换机绑定关系
package com.hh.rabbitmq.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;
@Configuration
public class HeadersRabbitConfig {
@Bean
public Queue headersQueue1() {
return new Queue("spring.headers.queue1");
}
@Bean
public Queue headersQueue2() {
return new Queue("spring.headers.queue2");
}
@Bean
public HeadersExchange headersExchange() {
return new HeadersExchange("spring.headers.exchange");
}
@Bean
public Binding headersBinding1() {
HashMap<String, Object> header = new HashMap<>();
header.put("queue", "queue1");
header.put("bindType", "whereAll");
return BindingBuilder.bind(headersQueue1()).to(headersExchange()).whereAll(header).match();
}
@Bean
public Binding headersBinding2() {
HashMap<String, Object> header = new HashMap<>();
header.put("queue", "queue2");
header.put("bindType", "whereAny");
return BindingBuilder.bind(headersQueue2()).to(headersExchange()).whereAny(header).match();
}
}
路由匹配规则:# 表示配置(0至多个),* 表示配置(只能接一个)
2.接口测试
package com.hh.rabbitmq.controller;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Random;
@RestController
public class RabbitController {
@Autowired
private AmqpTemplate amqpTemplate;
@RequestMapping(value = "sendHeadersMessage",method = RequestMethod.POST)
public String sendHeadersMessage(@RequestBody String message) {
try {
MessageProperties messageProperties = new MessageProperties();
messageProperties.setHeader("queue","queue1");
int i = (int) (new Random().nextDouble() * 10);
if (i % 10 == 0) {
messageProperties.setHeader("bindType","whereAll");
} else {
messageProperties.setHeader("bindType","whereAny");
}
Message mesProperties = new Message(message.getBytes(), messageProperties);
amqpTemplate.convertAndSend("spring.headers.exchange","",mesProperties);
} catch (Exception e) {
e.printStackTrace();
}
return "ok";
}
}
3.消费者监听队列进行消费
package com.hh.rabbitmq.config;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class ReceiverMessage {
@RabbitListener(queues = "spring.headers.queue1")
@RabbitHandler
public void getHeadersQueue1(String message) {
String[] split = message.split(",");
byte[] aByte = new byte[split.length];
for (int i = 0; i < split.length; i++) {
Byte aByte1 = Byte.valueOf(split[i]);
aByte[i] = aByte1;
}
System.out.println(new String(aByte));
}
}
总结
人生物语:幸福不仅在于物质的丰裕,幸福更在于精神的追求与心灵的充实以及灵魂的坦荡。