rabbitmq的几种模式:一共有7种模式
3,4,5三个模式涉及到交换机
安装rabbotmq到虚拟机里面 。默认账户guest,密码也是guest
进来之后可以看到管控台:
引入依赖:
在yml文件中 配置rabbitmq的信息:
rabbitmq:
host:192.168.10.101
username:guest
password:guest
virtual-host:/ //虚拟主机
port:5672
listener:
simple:
concurrency:10 //消费者的最小数量
max-concurrency:10 //消费者最大数量
prefetch:1 //限制消费者每次只处理一条消息,处理完再继续下一条消息
auto-startup:true //启动时是否默认启动容器,默认为true
default-requeue-rejected:true //被拒绝时重新进入队列
template:
Rabbitmq是一个典型的生产者消费者模型,创建一个队列queue
@Configuration
public class RabbitMQConfig
{
@Bean
public Queue queue()
{
return new Queue("queue",true);//队列名称就叫queue,消息持久化
}
}
消息发送方:发送对象
@Service
@Slf4j
public class MQSender
{
@Autowired
private RabbitTemplate rabbitTemplate;
public void send(Object msg)
{
//发送消息之前(发送的是一个对象),先把消息打印出来
log.info(msg);
//发送消息到队列里面
rabbitTemplate.convertAndSend("queue",msg);
}
}
消息接收方:消费者
@Service
@Slf4j
public class MQReceiver
{
@RabbitListener(queue="queue") //监听叫queue的这个队列
public void receive(Object msg)
{
//把消息打印出来
log.info(msg);
}
}
测试发送消息
@Controller
@RequestMapping("/user")
public class UserController
{
@Autowired
private MQSender mqSender;
@RequestMapping("/mq")
@ResponseBody
public void mq()
{
mqSender.send("Hello");
}
}
这个链接是消费者去连接的,因为发送者发完消息就会关掉,消费者会一直监听队列
发了消息之后:
fanout模式:发布订阅模式,也就是广播模式,消息可以被多个队列接收,多个队列接收的是同一个消费者发送的同一个消息
这里new了两个队列和一个交换机
@Configuration
public class RabbitMQConfig
{
@Bean
public Queue queue01()
{
return new Queue("queue01",true);//队列名称就叫queue,消息持久化
}
@Bean
public Queue queue02()
{
return new Queue("queue01",true);//队列名称就叫queue,消息持久化
}
@Bean //创建一个交换机
public FanoutExchange fanoutExchange()
{
return new FanoutExchange("fanoutExchange");
}
//将队列绑定到交换机上面去
@Bean
public Binding binding01()
{
return BindingBuilder.bind(queue01()).to(fanoutExchange());
}
@Bean
public Binding binding02()
{
return BindingBuilder.bind(queue02()).to(fanoutExchange());
}
}
然后消息发送方把消息发送到交换机里面,而不是队列中
@Service
@Slf4j
public class MQSender
{
@Autowired
private RabbitTemplate rabbitTemplate;
public void send(Object msg)
{
//发送消息之前(发送的是一个对象),先把消息打印出来
log.info(msg);
//发送消息到队列里面
rabbitTemplate.convertAndSend("fanoutExchange","",msg);
}
}
接收方(消费者)需要监听两个队列:
@Service
@Slf4j
public class MQReceiver
{
@RabbitListener(queue="queue01") //监听叫queue的这个队列
public void receive(Object msg)
{
//把消息打印出来
log.info(msg);
}
@RabbitListener(queue="queue02") //监听叫queue的这个队列
public void receive(Object msg)
{
//把消息打印出来
log.info(msg);
}
}
direct模式
你发送的消息里路由key是black,就会发送到queue2队列里面去
你发送的消息里路由key是orange,就会发送到queue1队列里面去
也就是说由路由key来指定发送到哪个队列里面
@Configuration
public class RabbitMQDirectConfig
{
@Bean
public Queue queue01()
{
return new Queue("queue01");//队列名称就叫queue,消息持久化
}
@Bean
public Queue queue02()
{
return new Queue("queue02");//队列名称就叫queue,消息持久化
}
//定义交换机
pubcli DirectExchange directExchange()
{
return new DirectExchange("direchExchange");
}
@Bean //绑定队列到交换机,需要带上路由键route key
public Binding binding01()
{
return BindingBuilder.bind(queue01()).to(directExchange()).with(queue.red);
}
@Bean //绑定队列到交换机,需要带上路由键route key
public Binding binding02()
{
return BindingBuilder.bind(queue02()).to(directExchange()).with(queue.green);
}
}
消息发送方:发送对象
@Service
@Slf4j
public class MQSender
{
@Autowired
private RabbitTemplate rabbitTemplate;
public void send01(Object msg)
{
//发送消息之前(发送的是一个对象),先把消息打印出来
log.info(msg);
//发送消息到交换机里面
rabbitTemplate.convertAndSend("directExchange","queue.red",msg);
}
public void send02(Object msg)
{
//发送消息之前(发送的是一个对象),先把消息打印出来
log.info(msg);
//发送消息到交换机里面
rabbitTemplate.convertAndSend("directExchange","queue.green",msg);
}
}
消息接收方:消费者
@Service
@Slf4j
public class MQReceiver
{
@RabbitListener(queue="queue01") //监听叫queue的这个队列
public void receive01(Object msg)
{
//把消息打印出来
log.info(msg);
}
@RabbitListener(queue="queue02") //监听叫queue的这个队列
public void receive02(Object msg)
{
//把消息打印出来
log.info(msg);
}
}
测试发送消息
@Controller
@RequestMapping("/user")
public class UserController
{
@Autowired
private MQSender mqSender;
@RequestMapping("/mq/direct01")
@ResponseBody
public void mq01()
{
mqSender.send01("Hello");
}
public void mq02("/mq/direct02")
{
mqSender.send02("World");
}
}
topic模式:其实也是路由key,只不过为了方便管理路由key(也就是说不再是一个route key对应一个队列,而是一组route key对应一个队列),用了通配符*和#,*是匹配一个词(一个单词而不是一个字母),#是匹配0个或多个
当一个消息携带的路由keyroute key 是quick.orange.rabbit时,那这个消息既符合1也符合2,所以会被发送给两个队列
当一个消息携带的路由keyroute key 是lazy.orange.elephant时,那这个消息既符合1也符合3,所以也会被发送给两个队列
不符合1,2,3那这条消息就会被抛弃
@Configuration
public class RabbitMQTopicConfig
{
@Bean
public Queue queue01()
{
return new Queue("queue01");//队列名称就叫queue,消息持久化
}
@Bean
public Queue queue02()
{
return new Queue("queue02");//队列名称就叫queue,消息持久化
}
//定义交换机
pubcli TopicExchange topicExchange()
{
return new TopicExchange("topicExchange");
}
@Bean //绑定队列到交换机,需要带上路由键route key
public Binding binding01()
{
return BindingBuilder.bind(queue01()).to(topicExchange()).with("#.queue.#");
}
@Bean //绑定队列到交换机,需要带上路由键route key
public Binding binding02()
{
return BindingBuilder.bind(queue02()).to(topicExchange()).with("*.queue.#");
}
}
消息发送方:发送对象
@Service
@Slf4j
public class MQSender
{
@Autowired
private RabbitTemplate rabbitTemplate;
public void send01(Object msg)
{
//发送消息之前(发送的是一个对象),先把消息打印出来
log.info(msg);
//发送消息到交换机里面
rabbitTemplate.convertAndSend("topicExchange","queue.red.message",msg);
}
public void send02(Object msg)
{
//发送消息之前(发送的是一个对象),先把消息打印出来
log.info(msg);
//发送消息到交换机里面
rabbitTemplate.convertAndSend("topicExchange","message.queue.green.abc",msg);
}
}
消息接收方:消费者
@Service
@Slf4j
public class MQReceiver
{
@RabbitListener(queue="queue01") //监听叫queue的这个队列
public void receive01(Object msg)
{
//把消息打印出来
log.info(msg);
}
@RabbitListener(queue="queue02") //监听叫queue的这个队列
public void receive02(Object msg)
{
//把消息打印出来
log.info(msg);
}
}
测试发送消息
@Controller
@RequestMapping("/user")
public class UserController
{
@Autowired
private MQSender mqSender;
@RequestMapping("/mq/topic01")
@ResponseBody
public void mq01()
{
mqSender.send01("Hello");
}
public void mq02("/mq/topic02")
{
mqSender.send02("World");
}
}
header模式基本己经被抛弃了