org.springframework.boot
spring-boot-starter-amqp
#rabbitMq配置
rabbitmq:
host: 127.0.0.1
port: 5672
username: test
password: 123456
virtual-host: /
listener:
direct:
retry:
enabled: true #消费失败开启重试
max-attempts: 5 #最多重试5次
根据消息携带的路由键将消息投递给对应队列
package com.lezu.springboot.configuration.rabbitmq;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DirectExchangeConfig {
public static final String DIRECT_QUEUE1 = "directQueue1";
public static final String DIRECT_QUEUE2 = "directQueue2";
public static final String DIRECT_EXCHANGE = "directExchange";
public static final String DIRECT_ROUTING_KEY = "direct";
//创建两个队列
@Bean
public Queue directQueue1() {
return new Queue(DIRECT_QUEUE1);
}
@Bean
public Queue directQueue2() {
return new Queue(DIRECT_QUEUE2);
}
//创建DirectExchange交换机
@Bean
public DirectExchange directExchange() {
return new DirectExchange(DIRECT_EXCHANGE);
}
//队列(DIRECT_QUEUE1) && 交换机 && 路由 进行绑定
@Bean
public Binding bindingDirectExchange1() {
return BindingBuilder.bind(directQueue1()).to(directExchange()).with(DIRECT_ROUTING_KEY);
}
//队列(DIRECT_QUEUE2) && 交换机 && 路由 进行绑定
@Bean
public Binding bindingDirectExchange2() {
return BindingBuilder.bind(directQueue2()).to(directExchange()).with(DIRECT_ROUTING_KEY);
}
}
生产者
package com.lezu.springboot.rabbitmq.producer;
import com.lezu.springboot.config.rabbitmq.DirectExchangeConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
@RequestMapping("/direct")
public class DirectController {
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* direct交换机为直连模式交换机
* 根据消息携带的路由键将消息投递给对应队列
*
* @return
*/
@RequestMapping("/send/{msg}")
public Object sendMsg(@PathVariable("msg") String msg) {
rabbitTemplate.convertAndSend(DirectExchangeConfig.DIRECT_EXCHANGE, DirectExchangeConfig.DIRECT_ROUTING_KEY, msg+"-------direct");
return "direct消息发送成功!!";
}
}
消费者
package com.lezu.springboot.rabbitmq.consumer;
import com.lezu.springboot.config.rabbitmq.DirectExchangeConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class DirectQueueListener {
/**
*
* 一个交换机可以绑定多个队列。如果通过路由key可以匹配到多个队列,消费的时候也只能有一个进行消费
* @param testMessage
*/
@RabbitListener(queues = DirectExchangeConfig.DIRECT_QUEUE1)
public void process(String testMessage) {
System.out.println("DirectReceiver消费者收到消息1 : " + testMessage);
}
@RabbitListener(queues = DirectExchangeConfig.DIRECT_QUEUE2)
public void process2(String testMessage) {
System.out.println("DirectReceiver消费者收到消息2 : " + testMessage);
}
}
测试http://localhost:8080/lezu/direct/send/rabbitMq
不涉及到路由的概念 只要绑定了这个交换机的队列都会收到来自生产者的消息
package com.lezu.springboot.configuration.rabbitmq;
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 FanoutExchangeConfig {
public static final String FANOUT_QUEUE1 = "fanoutQueue1";
public static final String FANOUT_QUEUE2 = "fanoutQueue2";
public static final String FANOUT_QUEUE3 = "fanoutQueue3";
public static final String FANOUT_EXCHANGE = "fanoutExchange";
public static final String FANOUT_ROUTING_KEY = "fanout";
@Bean
public Queue fanoutQueue1() {
return new Queue(FANOUT_QUEUE1);
}
@Bean
public Queue fanoutQueue2() {
return new Queue(FANOUT_QUEUE2);
}
@Bean
public Queue fanoutQueue3() {
return new Queue(FANOUT_QUEUE3);
}
@Bean
public FanoutExchange fanoutExchange() {
return new FanoutExchange(FANOUT_EXCHANGE);
}
@Bean
public Binding bindingFanoutExchange1() {
return BindingBuilder.bind(fanoutQueue1()).to(fanoutExchange());
}
@Bean
public Binding bindingFanoutExchange2() {
return BindingBuilder.bind(fanoutQueue2()).to(fanoutExchange());
}
@Bean
public Binding bindingFanoutExchange3() {
return BindingBuilder.bind(fanoutQueue3()).to(fanoutExchange());
}
}
生产者
package com.lezu.springboot.rabbitmq.producer;
import com.lezu.springboot.config.rabbitmq.FanoutExchangeConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
@RequestMapping("/fanout")
public class FanoutController {
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* fanout交换机为扇形模式交换机
* 消息会发送到所有绑定的队列上。
* @return
*/
@GetMapping("/send/{msg}")
public Object sendMsg(@PathVariable("msg") String msg) {
rabbitTemplate.convertAndSend(FanoutExchangeConfig.FANOUT_EXCHANGE, "", msg+"------fanout");
return "fanout消息发送成功!!";
}
}
消费者
package com.lezu.springboot.rabbitmq.consumer;
import com.lezu.springboot.config.rabbitmq.FanoutExchangeConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class FanoutQueueListener {
/**
* fanout交换机: 扇型交换机,这个交换机没有路由键概念,就算你绑了路由键也是无视的。 这个交
* 换机在接收到消息后,会直接转发到绑定到它上面的所有队列
* 同一个队列监听多次,只会消费一次。
* 交换机绑定的多个队列都可以收到消息
* @param testMessage
*/
@RabbitListener(queues = FanoutExchangeConfig.FANOUT_QUEUE1)
public void process1(String testMessage) {
System.out.println("FanoutReceiver消费者收到消息1 : " + testMessage);
}
//当多个队列绑定交换机不会被重复消费
// @RabbitListener(queues = FanoutExchangeConfig.FANOUT_QUEUE1)
// public void process2(String testMessage) {
// System.out.println("FanoutReceiver消费者收到消息2 : " + testMessage);
// }
@RabbitListener(queues = FanoutExchangeConfig.FANOUT_QUEUE2)
public void process2(String testMessage) {
System.out.println("FanoutReceiver消费者收到消息2 : " + testMessage);
}
@RabbitListener(queues = FanoutExchangeConfig.FANOUT_QUEUE3)
public void process3(String testMessage) {
System.out.println("FanoutReceiver消费者收到消息3 : " + testMessage);
}
}
测试http://localhost:8080/lezu/direct/send/测试11122
消费者中绑定到交换机中的时候,routingKey使用通配符模式。 topic.# 可匹配topic topic.add topic.add.add localhost:8080/lezu/topic/send/topic.123 topic.* 可匹配topic.add topic.delete localhost:8080/lezu/topic/send/topic.add #可匹配任意内容 localhost:8080/lezu/topic/send/我是任意内容
package com.lezu.springboot.configuration.rabbitmq;
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 TopicExchangeConfig {
public static final String TOPIC_QUEUE1 = "topicQueue1";
public static final String TOPIC_QUEUE2 = "topicQueue2";
public static final String TOPIC_QUEUE3 = "topicQueue3";
public static final String TOPIC_EXCHANGE = "topicExchange";
public static final String TOPIC_ROUTING_KEY = "topic*";
@Bean
public Queue topicQueue1() {
return new Queue(TOPIC_QUEUE1);
}
@Bean
public Queue topicQueue2() {
return new Queue(TOPIC_QUEUE2);
}
@Bean
public Queue topicQueue3() {
return new Queue(TOPIC_QUEUE3);
}
@Bean
public TopicExchange topicExchange() {
return new TopicExchange(TOPIC_EXCHANGE);
}
@Bean
public Binding bindingTopicExchange1() {
return BindingBuilder.bind(topicQueue1()).to(topicExchange()).with("topic.#");
}
@Bean
public Binding bindingTopicExchange2() {
return BindingBuilder.bind(topicQueue2()).to(topicExchange()).with("topic.*");
}
@Bean
public Binding bindingTopicExchange3() {
return BindingBuilder.bind(topicQueue3()).to(topicExchange()).with("#");
}
}
生产者
package com.lezu.springboot.rabbitmq.producer;
import com.lezu.springboot.config.rabbitmq.TopicExchangeConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
@RequestMapping("/topic")
public class TopicController {
private final RabbitTemplate rabbitTemplate;
public TopicController(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
}
@GetMapping("/send/{routingKey}")
public Object sendMsg(@PathVariable("routingKey") String routingKey) {
rabbitTemplate.convertAndSend(TopicExchangeConfig.TOPIC_EXCHANGE, routingKey, routingKey+"-------topic");
return "topic消息发送成功!!";
}
}
消费者
package com.lezu.springboot.rabbitmq.consumer;
import com.lezu.springboot.config.rabbitmq.TopicExchangeConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class TopicQueueListener {
/**
* topic: 主题交换机
*
* @param testMessage
*/
@RabbitListener(queues = TopicExchangeConfig.TOPIC_QUEUE1)
public void process(String testMessage) {
System.out.println("TopicReceiver消费者收到消息1 : " + testMessage);
}
@RabbitListener(queues = TopicExchangeConfig.TOPIC_QUEUE2)
public void process2(String testMessage) {
System.out.println("TopicReceiver消费者收到消息2 : " + testMessage);
}
@RabbitListener(queues = TopicExchangeConfig.TOPIC_QUEUE3)
public void process3(String testMessage) {
System.out.println("TopicReceiver消费者收到消息3 : " + testMessage);
}
}