交换器以及路由键
创建队列
创建交换器
绑定交换器以及路由键
点击创建的队列“demo-queue”,为队列绑定交换器以及路由键
routing key支持模糊匹配 比如routing-key.* 会将所有匹配此routing key的消息路由到此队列
📌routing-key.* 可以匹配到一个词,如 routing-key.demo
routing-key.# 可以匹配到多个词,如routing-key.demo、routing-key.demo.aaa
代码实现
📌即使不进行上面的手动创建操作,demo代码运行完后也会自动创建队列、交换器以及路由键
定义业务数据表类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DemoMessage implements Serializable {
private static final long serialVersionUID = -6827001717435315058L;
/**
* 消息Id
*/
private String messageId;
private String id;
private String name;
}
常量定义
interface MQConstants {
String QUEUE_NAME1 = "demo-queue";
String EXCHANGE_NAME1 = "demo-exchange";
String ROUTING_KEY_NAME1 = "routing-key.demo";
}
生产者
package com.strap.mydemo.components;
import com.strap.mydemo.constants.MyDemoConstants;
import com.strap.mydemo.entity.DemoMessage;
import lombok.extern.log4j.Log4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* <p>生产者</p>
*
* @author strap
*/
@Component
@Log4j
public class MqProducer {
private RabbitTemplate rabbitTemplate;
@Autowired
public MqProducer(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
}
public void send(DemoMessage message){
CorrelationData correlationData = new CorrelationData();
correlationData.setId(message.getMessageId());
rabbitTemplate.convertAndSend(
MyDemoConstants.MQConstants.EXCHANGE_NAME1, // 交换器
MyDemoConstants.MQConstants.ROUTING_KEY_NAME1, // 路由键
message, // 消息体
correlationData // 消息体唯一ID
);
log.info("生产者已发送消息:" + message);
}
}
设置消费者服务端配置
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
# 消费者服务配置
listener:
simple:
# 并发数
concurrency: 5
# 最大并发数
max-concurrency: 10
# 签收模式,auto自动签收,manual手动签收
acknowledge-mode: manual
# 限流 同一时间只能有一条消息过来
prefetch: 1
消费者
package com.strap.mydemo.components;
import cn.hutool.core.convert.Convert;
import com.strap.mydemo.constants.MyDemoConstants;
import com.strap.mydemo.entity.DemoMessage;
import com.rabbitmq.client.Channel;
import lombok.extern.log4j.Log4j;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* <p>消费者</p>
*
* @author strap
*/
@Component
@Log4j
public class MqConsumer {
public MqConsumer() {
}
@RabbitListener(
bindings = @QueueBinding(
value = @Queue(value = MyDemoConstants.MQConstants.QUEUE_NAME1, durable = "true"),
exchange = @Exchange(name = MyDemoConstants.MQConstants.EXCHANGE_NAME1, type = "topic"),
key = "routing-key.*"
)
)
@RabbitHandler // 指定消息过来时的处理方法
public void consume(@Payload DemoMessage message, @Headers Map<String, Object> headers , Channel channel) throws Exception{
log.info("消费者已拿到消息:" + message);
// 因为前面已设置手动签收模式,所以需要给mq响应消息已处理完,
channel.basicAck(
Convert.toLong(headers.get(AmqpHeaders.DELIVERY_TAG)),
false //是否批量接收
);
}
}
测试
package com.strap.mydemo;
import com.strap.mydemo.components.MqProducer;
import com.strap.mydemo.entity.DemoMessage;
import lombok.extern.log4j.Log4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
/**
* <p></p>
*
* @author strap
*/
@SpringBootTest(args = "--jasypt.encryptor.password=test123")
@Log4j
public class TestMQ {
private MqProducer mqProducer;
@Autowired
public TestMQ(MqProducer mqProducer) {
this.mqProducer = mqProducer;
}
@Test
public void test() {
mqProducer.send(
new DemoMessage("abc", "1", "小明")
);
}
}