既然是SpringBoot集成首先还是导入依赖了
spring-boot-starter-amqp对消息各种支持
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
配置文件
server: port: 9005 spring: rabbitmq: host: 106.14.107.226 port: 5672 username: guest password: guest virtual-host: / #虚拟主机 默认的 publisher-confirms: true #启用消息确认 listener: simple: acknowledge-mode: manual #消息手动确认
1.简单模式(简单队列就是一对一单生产单消费)
配置类
@Configuration
public class RabbitMqConfig {
@Bean
public Queue queue(){
return new Queue("hello");
}
}
发送者
@Component
public class HelloSender {
@Autowired
private AmqpTemplate amqpTemplate;
public void send(String test) {
this.amqpTemplate.convertAndSend("hello",test);
}
}
消费者
@Component
@RabbitListener(queues = "hello")
public class HelloReceiver {
@RabbitHandler
public void process(String test) {
System.out.println("Receiver:" + test);
}
}
总结:简单模式就是发送者直接发送消息到某个队列,很简单的。
2.工作模式(一对多)
配置类
@Configuration
public class RabbitMqConfig {
@Bean
public Queue queue(){
return new Queue("hello");
}
}
发送者
@Component
public class HelloSender {
@Autowired
private AmqpTemplate amqpTemplate;
public void send(String test) {
this.amqpTemplate.convertAndSend("hello",test);
}
}
消费者一
@Component
@RabbitListener(queues = "hello")
public class HelloReceiver1 {
@RabbitHandler
public void process(String test) {
System.out.println("Receiver1:" + test);
}
}
消费者二
@Component
@RabbitListener(queues = "hello")
public class HelloReceiver2 {
@RabbitHandler
public void process(String test) {
System.out.println("Receiver2:" + test);
}
}
总结:和简单模式对比工作模式就是多了一个消费者, 多个消费者同时去消费这一个队列,队列中的消息会被平均分摊给多个消费者进行处理。
3.Direct(路由模式)
发送者
@Component public class DirectSender { @Autowired private AmqpTemplate amqpTemplate; public void dicectSender(User user){ this.amqpTemplate.convertAndSend("direct-exchange", "direct.receiver", user); } }
里面三个参数分别是交换机,Routing_Key,发送的信息内容
消费者一
@Component public class DirectReceiver1 { @RabbitListener(bindings = @QueueBinding( value = @Queue(value = "user-direct", durable = "true"), exchange = @Exchange(name = "direct-exchange", durable = "true", type = "direct"), key = "direct.receiver")) @RabbitHandler public void dicectProcess1(User user) { System.out.println(user + "direct消息被消费"); } }
消费者二
@Component public class DirectReceiver2 { @RabbitListener(bindings = @QueueBinding( value = @Queue(value = "user-directs", durable = "true"), exchange = @Exchange(name = "direct-exchange", durable = "true", type = "direct"), key = "direct.receivers")) @RabbitHandler public void fanoutProcess1(User user){ System.out.println(user+"directs消息被消费"); } }
@QueueBinding 将交换机,队列,按指定的routingkey绑定起来
@Queue value队列名称,durable 是否持久化
@Exchange name交换机名称,durable 是否持久化,type交换机类型
key routingkey 路由规则
这个注解呢很强大,它可以直接帮我们创建交换机,队列,routingkey,然后把交换机和队列按指定的routingkey绑定起来。
下面我们执行下看看:
总结:我在发送信息时Routing_key 是direct.receiver,所以只有消费者一接收到了信息。direct 这种模式他就是将队列和交换机用一个Routing_key绑定起来,发布订阅指定的消息,注意:routingkey必须完全匹配消费者才能接收到信息。
4.Topic(路由模式-模糊匹配)
发送者
@Component public class TopicSender{ @Autowired private rabbitTemplate rabbitTemplate; public void topicSend(User user) { CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString()); this.rabbitTemplate.convertAndSend("topic-exchange", "topic.receiver", user,correlationData); this.rabbitTemplate.convertAndSend("topic-exchange", "topic.receivers", user,correlationData); } }
消费者
@Component public class TopicReceiver1 { @RabbitListener(bindings = @QueueBinding( value = @Queue(value = "user-topic", durable = "true"), exchange = @Exchange(name = "topic-exchange", durable = "true", type = "topic"), key = "topic.receiver")) @RabbitHandler public void topicProcess1(User user){ log.info(user+"topic消息被消费"); } }
消费者二
@Component public class TopicReceiver1 { @RabbitListener(bindings = @QueueBinding( value = @Queue(value = "user-topics", durable = "true"), exchange = @Exchange(name = "topic-exchange", durable = "true", type = "topic"), key = "topic.*")) @RabbitHandler public void topicProcess1(User user){ log.info(user+"topics消息被消费"); } }
还是老样子我们来看看执行结果:
总结:你们看他这个执行结果,队列topic消费到了一条信息,队列topics消费到了两条信息,因为topics队列的Routing_Key是采用了模糊匹配*号,所以它接收到了两条信息。总结一下就是呢,topic它也是一种路由模式,但他是可以模糊匹配的,比如user.*等价于 user.adb,user.#等于user.adb.abd.adb,*号它就相当于就是匹配一个单词,而#号呢匹配后面所有的,就是以user开头的Routing_Key都可以匹配到。
5.Fanou(广播模式)
发送者
@Component public class FanoutSender { @Autowired private AmqpTemplate amqpTemplate; /** * 1.指定的交换机 * 2.指定routingkey(广播模式不需要绑定routingkey,绑定了也不会生效) * 3.发送的消息 * @param user */ public void fanoutSender(User user){ amqpTemplate.convertAndSend("fanout-exchange","",user); }
消费者一
@Component public class FanoutReceiver1 { @RabbitListener(bindings = @QueueBinding( value = @Queue(value = "user-fanout", durable = "true"), exchange = @Exchange(name = "fanout-exchange", durable = "true", type = "fanout"))) @RabbitHandler public void fanoutProcess1(User user){ System.out.println(user+"fanout消息被消费"); } }
消费者二
@Component public class FanoutReceiver2 { @RabbitListener(bindings = @QueueBinding( value = @Queue(value = "user-fanouts", durable = "true"), exchange = @Exchange(name = "fanout-exchange", durable = "true", type = "fanout"))) @RabbitHandler public void fanoutProcess1(User user){ System.out.println(user+"fanouts消息被消费"); } }
最后我们来看看执行结果
我们指定的RoutingKey为空,最后两个消费者都消费到了,跟交换机绑定的队列都会收到消息。这就是订阅模式
我们只需要简单的将队列绑定到交换机上。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。就跟广播一样,Fanout交换机转发消息是最快的。