rabbitmq遵循AMQP协议,AMQP标准协议(协议介绍),springboot将整个过程化得编程封装得确实有时候让人不是很容易看懂。没关系,我们来讲讲怎么使用就好了。
springboot 1.x与2.x还是有挺大区别得。我这里使用得是springboot2.1.3.如有不一致地方可能是版本上得问题。
先看看官方文档得支持,地址:https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/reference/htmlsingle/#boot-features-rabbitmq
以上文档大致意思是说,rabbitmq是基于AMQP协议得,轻量级、可靠、可升级、可拔插得消息中间件,spring 通过AMQP协议与rabbitmq进行交互
在springboot中使用RabbitMQ 只需要配置spring.rabbitmq.*。例如你只需要配置以下属性就可以了。
#rabbitmq配置(springboot2.1.3)
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
# 开启发送确认
spring.rabbitmq.publisher-confirms=true
# 开启发送失败退回
spring.rabbitmq.publisher-returns=true
spring.rabbitmq.listener.type=simple
# 开启ACK
#spring.rabbitmq.listener.direct.acknowledge-mode=manual
spring.rabbitmq.listener.simple.acknowledge-mode=manual
# 开启ack限制,服务器如果没有收到ack,则不会继续往某个消费者继续发送消息
#限制每次发送一条数据。
spring.rabbitmq.listener.simple.prefetch=1
#spring.rabbitmq.listener.direct.prefetch=1
#spring.rabbitmq.listener.direct.consumers-per-queue=4
#同一个队列启动几个消费者
spring.rabbitmq.listener.simple.concurrency=2
#启动消费者最大数量
spring.rabbitmq.listener.simple.max-concurrency=3
#重试策略相关配置
spring.rabbitmq.listener.simple.retry.enabled=true
spring.rabbitmq.listener.simple.retry.stateless=false
spring.rabbitmq.listener.simple.retry.max-attempts=5
#时间策略乘数因子
spring.rabbitmq.listener.simple.retry.multiplier=1.0
spring.rabbitmq.listener.simple.retry.initial-interval=1000ms
spring.rabbitmq.listener.simple.retry.max-interval=10000ms
spring.rabbitmq.listener.simple.default-requeue-rejected=true
当然还有很多得配置,大家自己可以去试试,完整得配置文件请在这里查看
https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/reference/html/common-application-properties.html
(大家去看网络上其它得教程会发现配置文件少了一层 simple,或者direct,那就是springboot1.x版本了)
2.x修改messageListenerContainer,为SimpleMessageListenerContainer与DirectMessageListenerContainer
关于两者得区别可以参考 https://blog.csdn.net/yingziisme/article/details/86418580这边博客
springboot对MQ得支持已经简化到消息得发送使用 RabbitTemplate rabbitTemplate; 消息监听使用注解@
@RabbitListener(queues = "someQueue")//queues指的是队列名称(其中还有很多得属性,可以自行百度查阅相关属性得作用,也可以嵌套注解使用)
以@Bean得方式创建队列路由连接容器等。
总的来说非常方便,好下面上代码
RabbitConfig.java
package com.ydsh.framworks.config;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Auth yaozhongjie
* @Date 2019/3/14 17:53
**/
@Configuration
public class RabbitConfig {
@Bean
public Queue directQueue1() {
return new Queue(RabbitConstans.DIRECT_QUEUE1);
}
@Bean
public DirectExchange directExchange() {
return new DirectExchange(RabbitConstans.DIRECT_EXCHANGE);
}
@Bean
public Binding directBinding1() {
return BindingBuilder.bind(directQueue1()).to(directExchange()).with(RabbitConstans.DIRECT_BIND_KEY);
}
}
RabbitConstans.java
package com.ydsh.framworks.config;
/**
* @Auth yaozhongjie
* @Date 2019/3/18 11:57
**/
public class RabbitConstans {
//redirect模式
public static final String DIRECT_QUEUE1 = "direct.queue1";
public static final String DIRECT_EXCHANGE = "direct.exchange";
public static final String DIRECT_BIND_KEY ="direct.bind.key" ;
}
DirectSender.java
package com.ydsh.framworks.sender;
import com.ydsh.framworks.config.RabbitConstans;
import com.ydsh.framworks.entity.MqMessage;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @Auth yaozhongjie
* @Date 2019/3/18 10:43
**/
@Component
public class DirectSender implements RabbitTemplate.ReturnCallback {
@Autowired
RabbitTemplate rabbitTemplate;
public void send(MqMessage message){
rabbitTemplate.setReturnCallback(this);
this.rabbitTemplate.setConfirmCallback((data, ack, cause) -> {
if (!ack) {
System.out.println("消息发送失败" + cause + data.toString());
} else {
System.out.println("消息发送成功 ");
}
});
rabbitTemplate.convertAndSend(RabbitConstans.DIRECT_EXCHANGE,RabbitConstans.DIRECT_BIND_KEY,message);//这个message随便定义个对象,但是一定要实现序列化接口
}
@Override
public void returnedMessage(Message message, int i, String s, String s1, String s2) {
System.out.println("sender return success" + message.toString()+"==="+i+"==="+s1+"==="+s2);
}
}
DirectReciver.java
package com.ydsh.framworks.reciver;
import com.rabbitmq.client.Channel;
import com.ydsh.framworks.entity.MqMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.io.IOException;
/**
* @Auth yaozhongjie
* @Date 2019/3/18 10:45
**/
@Component
@RabbitListener(queues =RabbitConstans.DIRECT_QUEUE1)
@Slf4j //需要lombok包
public class DirectReciver {
@RabbitHandler
public void receiveTopic1(MqMessage mqMessage, Channel channel, Message message){
log.info("MqMessage:{}",mqMessage);
//拒绝消息 这边之前测试死信队列得时候做得
try {
channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
} catch (IOException e) {
e.printStackTrace();
}
//确认消息也就是回复ACK
/*try {
channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
log.info("receiver success");
} catch (IOException e) {
e.printStackTrace();
log.info("receiver fail");
}*/
}
}
好的就是这么简单。大家可以试试看