本文已参与「新人创作礼」活动,一起开启掘金创作之路。
六 Rabbitmq五种发送消息的模式代码实现
1. 简单模式(hello world)
步骤:
-
创建项目
- web/lombok/rabbitmq
-
编写配置文件
-
#mq配置 spring: rabbitmq: host: 192.168.200.132
-
-
创建队列----》Java Bean
import org.springframework.amqp.core.Queue; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration //声明是一个配置类 public class QueueConfig { /** * @Author: guodong * @Date: 11:33 2020/9/26 * @Parms [] * @ReturnType: org.springframework.amqp.core.Queue * @Description: 创建itheima-31队列 */ @Bean public Queue queue(){ return new Queue("itheima-31"); } } -
创建生产者发送消息
@RestController @RequestMapping("hello") @Slf4j public class HelloController { @Autowired private RabbitTemplate rabbitTemplate; @GetMapping("sendMsg/{msg}") public void sendMsg(@PathVariable String msg){ /* 第一个参数是routingkey: 路由键,默认是队列名称 第二个参数是发送的消息 */ rabbitTemplate.convertAndSend("itheima-31", msg); log.info("发送消息完毕 : {}" , msg); } } -
创建消费者监听消息
@RabbitListener(queues = "itheima-31") //声明监听的消息队列 @Slf4j @Component public class ConsumerListener { @RabbitHandler //转换消息 public void receiveMsg(String msg){ log.info("消费者接收到消息: {}" , msg); } }
2. 工作队列模式(work queue)
步骤:
- 复制粘贴,需要修改日志输出,以便查看是那个消费者接收到消息
小结:
-
工作队列模式特点:
- 消费者之间是竞争关系
- 消费者之间会进行轮训接收消息
- 以上两种模式共有的特点是不需要声明交换机,但是使用的是默认的交换机。
3. 发布订阅模式
- Fanout(广播类型交换机)
**步骤:**
0. 创建fanout类型交换机
0. 创建fanout.A、fanout.B、fanout.C
0. 完成三个队列与交换机的绑定
0. 发送消息
0. 编写三个消费者
**代码实现:**
- 创建队列+交换机并且完成绑定
```
/**
* @Author: guodong
* @Date: 12:06 2020/9/26
* @Parms []
* @ReturnType: org.springframework.amqp.core.FanoutExchange
* @Description: 创建fanout类型交换机
*/
@Bean
public FanoutExchange fanoutExchange(){
return new FanoutExchange("itheihei");
}
/*
bean在创建时默认的bean name是方法名
*/
@Bean
public Queue fanoutA(){
return new Queue("fanout.A");
}
@Bean
public Queue fanoutB(){
return new Queue("fanout.B");
}
@Bean
public Queue fanoutC(){
return new Queue("fanout.C");
}
/*
交换机与队列完成绑定
*/
@Bean
public Binding bindFanoutA(FanoutExchange fanoutExchange, Queue fanoutA){
return BindingBuilder.bind(fanoutA).to(fanoutExchange);
}
@Bean
public Binding bindFanoutB(FanoutExchange fanoutExchange, Queue fanoutB){
return BindingBuilder.bind(fanoutB).to(fanoutExchange);
}
@Bean
public Binding bindFanoutC(FanoutExchange fanoutExchange, Queue fanoutC){
return BindingBuilder.bind(fanoutC).to(fanoutExchange);
}
```
- 发送消息
```
@GetMapping("sendMsgEx/{msg}")
public void sendMsgEx(@PathVariable String msg){
/*
第一个参数是routingkey: 路由键,默认是队列名称
第二个参数是发送的消息
*/
rabbitTemplate.convertAndSend("itheihei", "", msg);
log.info("发送广播类型消息完毕 : {}" , msg);
}
```
- 接收消息
```
@RabbitListener(queues = "fanout.A") //声明监听的消息队列
@Slf4j
@Component
public class FanoutListenerA {
@RabbitHandler //转换消息
public void receiveMsg(String msg){
log.info("fanoutA 接收到消息: {}" , msg);
}
}
```
**小结:**
- 广播类型消息特点:
- 需要声明fanout类型交换机
- 需要完成交换机与队列的绑定
- 发送的消息可以被所有完成绑定的队列接收到,形成广播类型的消息
- Direct(路由键模式/点对点模式)
**步骤:**
- 创建交换机
- 创建队列
- 完成队列与交换机的绑定并且设置路由键
**小结:**
- direct模式的特点:
- 需要声明direct类型的交换机
- 完成队列与交换机的绑定并且需要设置路由键
- 在发送消息时需要指定路由键,只有符合规则(完全匹配)的路由键才可以将消息从交换机路由至队列,
- 如上图所示如果routingKey为itheima则A和B全部可以接收到消息,如果routingKey为itcast则只有B队列可以接收到消息
- Topic(主题模式/通配符模式)
**步骤:**
- 创建交换机
- 创建队列
- 完成队列与交换机的绑定并且设置路由键
**小结:**
- topic模式特点:
- 需要声明direct类型的交换机
- 完成队列与交换机的绑定并且需要设置路由键
- 在发送消息时需要指定路由键,只有符合规则才会路由至队列
- 规则:
- "*" : 不多不少正好匹配一个词
- "#": 匹配大于等于0个词
- 究竟有多少个词是用 "."来判断的
- 上图所示的案例中并且必须以itheima作为第一个词存在