为什么要用RabbitMQ
因为我们有很多场景需要用到消息中间件,比如异步发送消息啥的啥的,这里我就不多做解释了,大家应该都会的啊(怪我太懒了~)
工欲善其事 必先利其器
这里我是用的我的docker来安装RabbitMQ的客户端。(不会docker的可以去看看我的这一篇文章)
地址:CentOS-7安装Docker
- 下载rabbitmq镜像
docker pull rabbitmq:management // 这里注意management是版本的意思这个是带web管理界面的
- 启动镜像
docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin rabbitmq:management // 这里可以设置默认的用户和密码 我这里都设置为admin了
- 去浏览器输入你的ip地址:ip:15672(15672是管理界面的端口)
利器已经安装好了可以愉快的敲代码了
-
RabbitMQ 四种交换机模式:
-
Direct Pattern (此模式不需要配置交换机)
-
Fanout Pattern ( 类似于广播一样,将消息发送给和他绑定的队列 )
-
Topic Pattern ( 绑定交换机时可以做匹配。 #:表示零个或多个单词。*:表示一个单词 )
-
Header Pattern ( 带有参数的匹配规则 )
-
这里我只写了三种模式的示例(因为我想偷懒)
引入maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
添加配置
spring:
application:
name: rabbitmq
rabbitmq:
host: 你的ip
port: 5672
username: 设置的用户名
password: 设置的密码
写个配置类
@Configuration
public class RabbitConfig {
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
// 创建消息连接
RabbitTemplate template = new RabbitTemplate(connectionFactory);
// 消息设置为json类型
template.setMessageConverter(new Jackson2JsonMessageConverter());
return template;
}
}
写个固定值(这里是为了方便调用)
public interface MQconst {
/**
* 队列
*/
String TEST_QUEUE="queue.test";
String TEST_QUEUE1="queue.test1";
String TEST_QUEUE2="queue.test2";
String TEST_QUEUE3="queue.test3";
/**
* 主题
*/
String TEST_TOPIC="topic.test";
/**
*广播
*/
String TEST_BROADCAST="broadcast.test";
/**
*路由key
*/
String TEST_ROUTEKEY="sys.test";
}
写个队列和交换机绑定类
@Configuration("testQueueDeclaration")
public class QueueDeclaration implements MQconst {
/**
* 队列
* @return
*/
@Bean("testQueue")
public Queue testQueue() {
return new Queue(TEST_QUEUE);
}
@Bean("testQueue1")
public Queue testQueue1() {
return new Queue(TEST_QUEUE1);
}
@Bean("testQueue2")
public Queue testQueue2() {
return new Queue(TEST_QUEUE2);
}
@Bean("testQueue3")
public Queue testQueue3() {
return new Queue(TEST_QUEUE3);
}
/**
* 交换机
* @return
*/
@Bean("testTopic")
public TopicExchange testTopic() {
return new TopicExchange(TEST_TOPIC);
}
/**
* test-广播消息交换机
* @return
*/
@Bean("testBroadcast")
public FanoutExchange testBroadcast() {
return new FanoutExchange(TEST_BROADCAST);
}
/**
* 绑定
* @return
*/
@Bean("testBind")
public Binding testBind(@Qualifier("testQueue") Queue testQueue, TopicExchange testTopic) {
return BindingBuilder.bind(testQueue).to(testTopic).with(TEST_ROUTEKEY);
}
@Bean("testBind1")
public Binding testBind1(@Qualifier("testQueue1")Queue testQueue, FanoutExchange testBroadcast) {
return BindingBuilder.bind(testQueue).to(testBroadcast);
}
@Bean("testBind2")
public Binding testBind2(@Qualifier("testQueue2") Queue testQueue, FanoutExchange testBroadcast) {
return BindingBuilder.bind(testQueue).to(testBroadcast);
}
}
准备充足可以开始了
direct模式
- 消费者
@Component
@RabbitListener(queues = MQconst.TEST_QUEUE3) // 监听你要接收消息的队列
public class TestConsume5 implements BaseConsume { // 这里只是我写了个默认的发消息接口你们可以不用实现这个接口
@Override
@RabbitHandler // 拦截消息
public void consume(Object data) {
System.out.println("direct收到消息=》"+data.toString());
}
}
- 生产者
@Component
public class TestDirectProduce implements BaseProduce { // 默认发消息的接口可以不实现
@Autowired
private AmqpTemplate amqpTemplate; // rabbitmq发送消息接口
@Override
public String produce(Object message) {
try {
// 发送消息第一个参数是你的队列,第二个是消息
amqpTemplate.convertAndSend(MQconst.TEST_QUEUE3,message);
}catch (Exception e){
}
return "发送成功~";
}
}
- 结果
Fanout 模式(俗称广播模式)
- 消费者1
@Component
@RabbitListener(queues = MQconst.TEST_QUEUE1)
public class TestConsume3 implements BaseConsume {
@Override
@RabbitHandler
public void consume(Object data) {
System.out.println("boradcast收到消息1=》"+data.toString());
}
}
- 消费者2
@Component
@RabbitListener(queues = MQconst.TEST_QUEUE2)
public class TestConsume4 implements BaseConsume {
@Override
@RabbitHandler
public void consume(Object data) {
System.out.println("boradcast收到消息2=》"+data.toString());
}
}
- 生产者(这里要注意广播模式只会发消息给绑定在此交换机下的队列,不明白的可以去看我上面写的队列和交换机绑定类)
@Component
@Slf4j
public class TestBoradcastProduce implements BaseProduce {
@Autowired
private AmqpTemplate amqpTemplate;
@Override
public String produce(Object message) {
String exchange=exchange();
try {
// 第一个参数是交换机,第二个需要为空,第三个消息
amqpTemplate.convertAndSend(exchange,null,message);
log.debug("消息发布成功{}", message);
}catch (Exception e){
log.error("消息发布异常{},{}", message, e.getStackTrace());
}
return "发送成功~";
}
public String exchange() {
// 交换机
return MQconst.TEST_BROADCAST;
}
}
- 结果
未完待续(跑路了吃不了学习的苦)