12)SprintBoot 2.X 集成RabbitMQ
1. pom.xml中添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
2. application.properties中添加配置
#rabbitmq
spring.rabbitmq.host=47.103.118.58
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.virtual-host=/
spring.rabbitmq.listener.simple.concurrency= 10
spring.rabbitmq.listener.simple.max-concurrency= 10
#每次取队列取几个
spring.rabbitmq.listener.simple.prefetch= 1
spring.rabbitmq.listener.simple.auto-startup=true
#消费者消费失败后重新加载到队列中
spring.rabbitmq.listener.simple.default-requeue-rejected= true
#是否启动重试
spring.rabbitmq.template.retry.enabled=true
spring.rabbitmq.template.retry.initial-interval=1000ms
spring.rabbitmq.template.retry.max-attempts=3
spring.rabbitmq.template.retry.max-interval=10000ms
spring.rabbitmq.template.retry.multiplier=1.0
3. 4种交换机模式实现(Direct、Topic、Fanout、Headers),具体原理参考1,具体原理参考2
类型名称 | 类型描述 |
---|
Fandout | 把所有发送到该Exchange的消息路由到所有与它绑定的Queue中 |
Direct | Routing Key==Binding Key |
Topic | 模糊匹配 |
Headers | Exchange不依赖于routing key与binding key的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。 |
3.1 消息发送者Sender
@Service
public class MQSender {
private static final Logger logger = LoggerFactory.getLogger(MQReceiver.class);
@Autowired
AmqpTemplate amqpTemplate;
public void send(Object message){
String msg = RedisService.Bean2String(message);
logger.info("send topic message: " + msg);
amqpTemplate.convertAndSend(MQConfig.QUEUE, msg);
}
public void sendTopic(Object message){
String msg = RedisService.Bean2String(message);
logger.info("send topic message: " + msg);
amqpTemplate.convertAndSend(MQConfig.TOPIC_EXCHANGE,"topic.key1",msg+"1");
amqpTemplate.convertAndSend(MQConfig.TOPIC_EXCHANGE,"topic.key2",msg+"1");
}
public void sendFanout(Object message){
String msg = RedisService.Bean2String(message);
logger.info("send fanout message: " + msg);
amqpTemplate.convertAndSend(MQConfig.FANOUT_EXCHANGE,"",msg+"1");
}
public void sendHeaders(Object message){
String msg = RedisService.Bean2String(message);
logger.info("send headers message: " + msg);
MessageProperties properties = new MessageProperties();
properties.setHeader("header1","value1");
properties.setHeader("header2","value2");
Message obj = new Message(msg.getBytes(),properties);
amqpTemplate.convertAndSend(MQConfig.HEADERS_EXCHANGE,"",obj);
}
}
3.2 队列配置
@Configuration
public class MQConfig {
public static final String QUEUE = "queue";
public static final String TOPIC_QUEUE1 = "topic.queue1";
public static final String TOPIC_QUEUE2 = "topic.queue2";
public static final String FANOUT_QUEUE1 = "fanout.queue1";
public static final String FANOUT_QUEUE2 = "fanout.queue2";
public static final String HEADERS_QUEUE = "headers.queue";
public static final String TOPIC_EXCHANGE = "topicExchange";
public static final String FANOUT_EXCHANGE = "fanoutExchange";
public static final String HEADERS_EXCHANGE = "headersExchange";
@Bean
public Queue queue() {
return new Queue(QUEUE,true);
}
@Bean
public Queue topicQueue1(){
return new Queue(TOPIC_QUEUE1,true);
}
@Bean
public Queue topicQueue2(){
return new Queue(TOPIC_QUEUE2,true);
}
@Bean
public TopicExchange topicExchange(){
return new TopicExchange(TOPIC_EXCHANGE);
}
@Bean
public Binding topicBinding1(){
return BindingBuilder.bind(topicQueue1()).to(topicExchange()).with("topic.key1");
}
@Bean
public Binding topicBinding2(){
return BindingBuilder.bind(topicQueue2()).to(topicExchange()).with("topic.#");
}
@Bean
public Queue fanoutQueue1(){
return new Queue(FANOUT_QUEUE1,true);
}
@Bean
public Queue fanoutQueue2(){
return new Queue(FANOUT_QUEUE2,true);
}
@Bean
public FanoutExchange fanoutExchange(){
return new FanoutExchange(FANOUT_EXCHANGE);
}
@Bean
public Binding fanoutBinding1(){
return BindingBuilder.bind(fanoutQueue1()).to(fanoutExchange());
}
@Bean
public Binding fanoutBinding2(){
return BindingBuilder.bind(fanoutQueue2()).to(fanoutExchange());
}
@Bean
public HeadersExchange headersExchange(){
return new HeadersExchange(HEADERS_EXCHANGE);
}
@Bean
public Queue headersQueue(){
return new Queue(HEADERS_QUEUE,true);
}
@Bean
public Binding headersBinding(){
Map<String, Object> map = new HashMap<>();
map.put("header1","value1");
map.put("header2","value2");
return BindingBuilder.bind(headersQueue()).to(headersExchange()).whereAll(map).match();
}
}
3.3 消息接收者Receiver
@Service
public class MQReceiver {
private static final Logger logger = LoggerFactory.getLogger(MQReceiver.class);
@RabbitListener(queues = MQConfig.QUEUE)
public void receive(String message){
logger.info("receive message" + message);
}
@RabbitListener(queues = MQConfig.TOPIC_QUEUE1)
public void receiveTopic1(String message){
logger.info("receive topic queue1 message: " + message);
}
@RabbitListener(queues = MQConfig.TOPIC_QUEUE2)
public void receiveTopic2(String message){
logger.info("receive topic queue2 message: " + message);
}
@RabbitListener(queues = MQConfig.FANOUT_QUEUE1)
public void receiveFanout1(String message){
logger.info("receive fanout queue1 message: " + message);
}
@RabbitListener(queues = MQConfig.FANOUT_QUEUE2)
public void receiveFanout2(String message){
logger.info("receive fanout queue2 message: " + message);
}
@RabbitListener(queues = MQConfig.HEADERS_QUEUE)
public void receiveFanout2(byte[] message){
logger.info("receive headers queue message: " + new String(message));
}
}
3.4 消息队列的Controller使用
@Controller
@RequestMapping("/demo")
public class sampleController {
@Autowired
UserService userService;
@Autowired
RedisService redisService;
@Autowired
MQSender sender;
@RequestMapping("/mq/headers")
@ResponseBody
public Result<String> headers() {
sender.sendHeaders("hello,lianghj");
return Result.success("hello,lianghj");
}
@RequestMapping("/mq/fanout")
@ResponseBody
public Result<String> fanout() {
sender.sendFanout("hello,lianghj");
return Result.success("hello,lianghj");
}
@RequestMapping("/mq/topic")
@ResponseBody
public Result<String> mq() {
sender.sendTopic("hello,lianghj");
return Result.success("hello,lianghj");
}
@RequestMapping("/mq")
@ResponseBody
public Result<String> topic () {
sender.send("hello,lianghj");
return Result.success("hello,lianghj");
}
}