目录
工作流程
是否携带routingKey | 是否绑定routingKey | |
---|---|---|
Direct | 是 | 是 |
Fanout | 否 | 否 |
Topic | 是 | 是 |
Header | 否 | 否 |
配置公共部分
开始之前请务必确保rabbitmq在自己的环境里已经安装好
创建SpringBoot项目
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
yml文件配置rabbitmq信息
spring:
application:
name: rabbitmq-demo
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
常量
public class RabbitMQConst {
public static final String DIRECT_EXCHANGE = "DIRECT_EXCHANGE";
public static final String DIRECT_QUEUE = "DIRECT_QUEUE";
public static final String DIRECT_ROUTING_KEY = "DIRECT_ROUTING_KEY";
public static final String FANOUT_EXCHANGE = "FANOUT_EXCHANGE";
public static final String FANOUT_QUEUE_A = "FANOUT_QUEUE_A";
public static final String FANOUT_QUEUE_B = "FANOUT_QUEUE_B";
public static final String TOPIC_EXCHANGE = "TOPIC_EXCHANGE";
public static final String TOPIC_QUEUE_A = "TOPIC_QUEUE_A";
public static final String TOPIC_QUEUE_B = "TOPIC_QUEUE_B";
public static final String TOPIC_QUEUE_C = "TOPIC_QUEUE_C";
public static final String HEADER_EXCHANGE = "HEADER_EXCHANGE";
public static final String HEADER_QUEUE_A = "HEADER_QUEUE_A";
public static final String HEADER_QUEUE_B = "HEADER_QUEUE_B";
}
四种模式
Direct Exchange
点对点模式
配置
@Configuration
public class DirectExchangeConfig {
@Bean
public Queue directQueue() {
return new Queue(RabbitMQConfig.DIRECT_QUEUE, true, false, false);
}
@Bean
public DirectExchange directExchange() {
return new DirectExchange(RabbitMQConfig.DIRECT_EXCHANGE, true, false);
}
@Bean
public Binding bindDirect() {
return BindingBuilder.bind(directQueue())
.to(directExchange())
.with(RabbitMQConfig.DIRECT_ROUTING_KEY);
}
}
生产者
@RestController
public class DirectProduceController {
@Resource
private RabbitTemplate rabbitTemplate;
@GetMapping("/direct/{msg}")
public void produce(@PathVariable String msg) {
rabbitTemplate.convertAndSend(RabbitMQConfig.DIRECT_EXCHANGE, RabbitMQConfig.DIRECT_ROUTING_KEY, msg);
}
}
消费者
@Component
@Slf4j
public class DirectConsumerService {
@RabbitListener(queues = RabbitMQConfig.DIRECT_QUEUE)
public void consume(String msg) {
log.info("Direct queue->consume: {}", msg);
}
}
Fanout exchange
发布订阅,只要产生一条数据,这条数据会分发到所有的队列上
配置
@Configuration
public class FanoutExchangeConfig {
@Bean Queue fanoutQueueA() {
return new Queue(RabbitMQConfig.FANOUT_QUEUE_A);
}
@Bean Queue fanoutQueueB() {
return new Queue(RabbitMQConfig.FANOUT_QUEUE_B);
}
@Bean FanoutExchange fanoutExchange() {
return new FanoutExchange(RabbitMQConfig.FANOUT_EXCHANGE, true, false);
}
@Bean Binding bindFanoutA() {
return BindingBuilder.bind(fanoutQueueA()).to(fanoutExchange());
}
@Bean Binding bindFanoutB() {
return BindingBuilder.bind(fanoutQueueB()).to(fanoutExchange());
}
}
生产者
@RestController
public class FanoutProduceController {
@Resource
RabbitTemplate rabbitTemplate;
@GetMapping("/fanout/{msg}")
public void produce(@PathVariable String msg) {
rabbitTemplate.convertAndSend(RabbitMQConfig.FANOUT_EXCHANGE, "", msg);
}
}
消费者
@Service
@Slf4j
public class FanoutConsumerService {
@RabbitListener(queues = { RabbitMQConfig.FANOUT_QUEUE_A })
public void consumerA(String msg) {
log.info("Fanout queueA->consume: {}", msg);
}
@RabbitListener(queues = { RabbitMQConfig.FANOUT_QUEUE_B })
public void consumerB(String msg) {
log.info("Fanout queueB->consume: {}", msg);
}
}
Topic Exchange
匹配模式
- * (star) can substitute for exactly one word.(只能匹配有且仅有一个字符)
a.* 可以匹配"a.“, “a.a”, “a.ab”,但是不能匹配"a”, “a.b.c”
- # (hash) can substitute for zero or more words.(只能匹配0至多个字符)
a.#可以匹配"a",“a.a”, “a.b.c”
配置
@Configuration
public class TopicExchangeConfig {
@Bean TopicExchange topicExchange() {
return new TopicExchange(RabbitMQConfig.TOPIC_EXCHANGE, true, false);
}
@Bean Queue topicQueueA() {
return new Queue(RabbitMQConfig.TOPIC_QUEUE_A);
}
@Bean Queue topicQueueB() {
return new Queue(RabbitMQConfig.TOPIC_QUEUE_B);
}
@Bean Queue topicQueueC() {
return new Queue(RabbitMQConfig.TOPIC_QUEUE_C);
}
@Bean Binding bindTopicA() {
return BindingBuilder.bind(topicQueueA()).to(topicExchange()).with("a.*");
}
@Bean Binding bundTopicB() {
return BindingBuilder.bind(topicQueueB()).to(topicExchange()).with("b.*");
}
@Bean Binding bindTopicC() {
return BindingBuilder.bind(topicQueueC()).to(topicExchange()).with("rabbit.#");
}
}
生产者
@RestController
public class TopicProduceController {
@Resource
RabbitTemplate rabbitTemplate;
@GetMapping("/topic")
public void produce(@RequestParam(name = "msg")String msg, @RequestParam(name = "routingKey") String routingKey) {
Map<String, Object> map = new HashMap<>();
map.put("msg", msg);
map.put("routingKey", routingKey);
rabbitTemplate.convertAndSend(RabbitMQConfig.TOPIC_EXCHANGE, routingKey, map.toString());
}
}
消费者
@Component
@Slf4j
public class TopicConsumeService {
@RabbitListener(queues = { RabbitMQConfig.TOPIC_QUEUE_A })
public void consumeA(String ms) {
log.info("Topic queueA->consume: {}", ms);
}
@RabbitListener(queues = { RabbitMQConfig.TOPIC_QUEUE_B })
public void consumeB(String ms) {
log.info("Topic queueB->consume: {}", ms);
}
@RabbitListener(queues = { RabbitMQConfig.TOPIC_QUEUE_C })
public void consumeC(String ms) {
log.info("Topic queueC->consume: {}", ms);
}
}
Headers Exchange
配置
@Configuration
public class HeaderExchangeConfig {
@Bean HeadersExchange headersExchange() {
return new HeadersExchange(RabbitMQConfig.HEADER_EXCHANGE);
}
@Bean Queue headersQueueA() {
return new Queue(RabbitMQConfig.HEADER_QUEUE_A);
}
@Bean Queue headersQueueB() {
return new Queue(RabbitMQConfig.HEADER_QUEUE_B);
}
@Bean Binding bindHeadersA() {
Map<String, Object> map = new HashMap<>();
map.put("A_one", "one");
map.put("A_two", "two");
// 匹配任意一个就行
return BindingBuilder.bind(headersQueueA()).to(headersExchange())
.whereAny(map).match();
}
@Bean Binding bindHeadersB() {
Map<String, Object> map = new HashMap<>();
map.put("B_one", "one");
map.put("B_two", "two");
// 全匹配
return BindingBuilder.bind(headersQueueB()).to(headersExchange())
.whereAll(map).match();
}
}
生产者
@RestController
public class HeaderProduceController {
@Resource
private RabbitTemplate rabbitTemplate;
@GetMapping("/header")
public void produce(@RequestParam(name = "key") String key, @RequestParam(name = "value") String value,
@RequestParam(name = "msg") String msg) {
Map<String, Object> map = new HashMap<>();
map.put(key, value);
MessageProperties messageProperties = new MessageProperties();
messageProperties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);
messageProperties.setContentType("UTF-8");
messageProperties.getHeaders().putAll(map);
Message message = new Message(msg.getBytes(), messageProperties);
rabbitTemplate.convertAndSend(RabbitMQConfig.HEADER_EXCHANGE, "", message);
}
}
消费者
@Component
@Slf4j
public class HeaderConsumerService {
@RabbitListener(queues = { RabbitMQConfig.HEADER_QUEUE_A })
public void consumeA(Message message) throws UnsupportedEncodingException {
MessageProperties messageProperties = message.getMessageProperties();
String contentType = messageProperties.getContentType();
log.info("Header queueA->consume: {}", new String(message.getBody(), contentType));
}
@RabbitListener(queues = { RabbitMQConfig.HEADER_QUEUE_B })
public void consumeB(Message message) throws UnsupportedEncodingException {
MessageProperties messageProperties = message.getMessageProperties();
String contentType = messageProperties.getContentType();
log.info("Header queueB->consume: {}", new String(message.getBody(), contentType));
}
}