前面的学习都是基于原生的api,下面我们使用spingboot来整合rabbitmq

springboot对rabbitmq提供了友好支持,极大的简化了开发流程

引入maven


<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

配置yml


rabbitmq:
host: 47.102.103.232
port: 5672
username: admin
password: admin
virtual-host: /test
publisher-confirms: true
publisher-returns: true
cache:
channel:
size: 10
listener:
simple:
acknowledge-mode: manual
concurrency: 1
max-concurrency: 3
retry:
enabled: true

这是基础的配置,看不懂的配置后面会介绍

更详细的配置参考官方https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/reference/htmlsingle/#boot-features-rabbitmq(搜索rabbit往下拉即可)

代码实现


配置类

@Configuration
public class RabbitConfig {
@Bean
public Queue helloQueue() {
return new Queue("helloQueue");
}
   //创建topic交换机
@Bean
public TopicExchange helloExchange() {
return new TopicExchange("helloExchange");
}
@Bean
public Binding bindingPaymentExchange(Queue helloQueue, TopicExchange helloExchange) {
return BindingBuilder.bind(helloQueue).to(helloExchange).with("hello.#");
}
/**
* 定制化amqp模版
   * connectionFactory:包含了yml文件配置参数
*/
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
// 必须设置为 true,不然当 发送到交换器成功,但是没有匹配的队列,不会触发 ReturnCallback 回调
// 而且 ReturnCallback 比 ConfirmCallback 先回调,意思就是 ReturnCallback 执行完了才会执行 ConfirmCallback
rabbitTemplate.setMandatory(true);
// 设置 ConfirmCallback 回调 yml需要配置 publisher-confirms: true
rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
       // 如果发送到交换器都没有成功(比如说删除了交换器),ack 返回值为 false
// 如果发送到交换器成功,但是没有匹配的队列(比如说取消了绑定),ack 返回值为还是 true (这是一个坑,需要注意)
if (ack) {
String messageId = correlationData.getId();
System.out.println("confirm:"+messageId);
}
});
// 设置 ReturnCallback 回调 yml需要配置 publisher-returns: true
// 如果发送到交换器成功,但是没有匹配的队列,就会触发这个回调
rabbitTemplate.setReturnCallback((message, replyCode, replyText,
exchange, routingKey) -> {
String messageId = message.getMessageProperties().getMessageId();
System.out.println("return:"+messageId);
});
return rabbitTemplate;
}
}
回调机制
  • 消息不管是否投递到交换机都进行ConfirmCallback回调,投递成功ack=true,否则为false
  • 交换机匹配到队列成功则不进行ReturnCallback回调,否则先进行ReturnCallback回调再进行ConfirmCallback回调
  • 如果消息成功投递到交换机,但没匹配到队列,则ConfirmCallback回调ack仍为true

生产者

@Component
public class RbProducer {
//注意一定要使用RabbitTemplate!!
//虽然RabbitTemplate实现了AmqpTemplate 但是AmqpTemplate里并没有能发送correlationData的方法
@Resource
private RabbitTemplate rbtemplate;
public void send1(String msg){
//CorrelationData用于confirm机制里的回调确认
CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
rbtemplate.convertAndSend("helloExchange", "hello.yj", msg,correlationData);
}
public void send2(User user){
CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
rbtemplate.convertAndSend("helloExchange", "hello.yj", user,correlationData);
}
}

消费者

@Component
@RabbitListener(queues = "helloQueue")
public class RbConsumer {
@RabbitLister(queues = "helloQueue")
public void receive0(Message msg, Channel channel) throws IOException {
System.out.println("consumer receive message0: " + msg);
channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false);
}
@RabbitHandler
public void receive1(String msg, @Header(AmqpHeaders.DELIVERY_TAG)long deliveryTag, Channel channel) throws IOException {
System.out.println("consumer receive message1: " + msg);
channel.basicAck(deliveryTag, false);
}
@RabbitHandler
public void receive2(User user, @Header(AmqpHeaders.DELIVERY_TAG)long deliveryTag, Channel channel) throws IOException {
System.out.println("consumer receive message2: "+user);
     //如果发生以下情况投递消息所有的通道或连接被突然关闭(包括消费者端丢失TCP连接、消费者应用程序(进程)挂掉、通道级别的协议异常)任何已经投递的消息但是没有被消费者端确认的消息会自动重新排队。
//请注意,连接检测不可用客户端需要一段时间才会发现,所以会有一段时间内的所有消息会重新投递
//因为消息的可能重新投递,所有必须保证消费者端的接口的幂等。 //在RabbitMQ中影响吞吐量最大的参数是:消息确认模式和Qos预取值
//自动消息确认模式或设置Qos预取值为无限虽然可以最大的提高消息的投递速度,但是在消费者端未及时处理的消息的数量也将增加,从而增加消费者RAM消耗,使用消费者端奔溃。所以以上两种情况需要谨慎使用。
//RabbitMQ官方推荐Qos预取值设置在 100到300范围内的值通常提供最佳的吞吐量,并且不会有使消费者奔溃的问题
channel.basicAck(deliveryTag, false);
channel.basicQos(100);
// 代表消费者拒绝一条或者多条消息,第二个参数表示一次是否拒绝多条消息,第三个参数表示是否把当前消息重新入队
// channel.basicNack(deliveryTag, false, false);
// 代表消费者拒绝当前消息,第二个参数表示是否把当前消息重新入队
// channel.basicReject(deliveryTag,false);
}
}

@RabbitListener+@RabbitHandler:消费者监听

  使用@RabbitListener+@RabbitHandler组合进行监听,监听器会根据队列发来的消息类型自动选择处理方法

channel.basicAck(deliveryTag, false):手动确认机制

  deliverTag:该消息的标识,每来一个消息该标识+1

  multiple:第二个参数标识书否批量确认

  requeue:被拒绝的是否重新入队

channel.basicQos(100):最多未确认的消息数量为100,超过100队列将停止给该消费者投递消息

更多参数详解参考https://www.cnblogs.com/piaolingzxh/p/5448927.html

测试


@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestBoot.class)
public class TestRabbit {
@Resource
private RbProducer producer;
@Test
public void send1() {
producer.send1("hello,im a string");
}
@Test
public void send2() {
User user = new User();
user.setNickname("hello,im a object");
producer.send2(user);
}
}

成功消费

完结

下篇博客我们讨论下在拥有了手动ack机制、confirm机制、return机制后,是否真的可靠~

rabbitmq学习(七) —— springboot下的可靠使用的更多相关文章

  1. RabbitMQ学习在windows下安装配置

    RabbitMQ学习一. 在windows下安装配置 1.下载并安装erlang,http://www.erlang.org/download.html,最新版是R15B01(5.9.1).由于我机器 ...

  2. SpringBoot学习(七)-->SpringBoot在web开发中的配置

    SpringBoot在web开发中的配置 Web开发的自动配置类:在Maven Dependencies-->spring-boot-1.5.2.RELEASE.jar-->org.spr ...

  3. RabbitMQ学习系列三:.net 环境下 C#代码订阅 RabbitMQ 消息并处理

    上一篇已经讲了Rabbitmq如何在Windows平台安装 不懂请移步: RabbitMQ学习系列二:.net 环境下 C#代码使用 RabbitMQ 消息队列 一.理论 .net环境下,C#代码订阅 ...

  4. rabbitmq学习(五):springboot整合rabbitmq

    一.Springboot对rabbitmq的支持 springboot提供了对rabbitmq的支持,并且大大简化了rabbitmq的相关配置.在springboot中,框架帮我们将不同的交换机划分出 ...

  5. RabbitMQ学习总结 第三篇:工作队列Work Queue

    目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...

  6. RabbitMQ学习总结 第二篇:快速入门HelloWorld

    目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...

  7. (转)RabbitMQ学习

    (二期)24.消息中间件RabbitMq [课程24]RabbitM...概念.xmind60.2KB [课程24]五种队列模式.xmind0.8MB [课程24]消息确...rm).xmind84. ...

  8. 官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群

    在第二节我们进行了RabbitMQ的安装,现在我们就RabbitMQ进行集群的搭建进行学习,参考官网地址是:http://www.rabbitmq.com/clustering.html 首先我们来看 ...

  9. 官网英文版学习——RabbitMQ学习笔记(一)认识RabbitMQ

    鉴于目前中文的RabbitMQ教程很缺,本博主虽然买了一本rabbitMQ的书,遗憾的是该书的代码用的不是java语言,看起来也有些不爽,且网友们不同人学习所写不同,本博主看的有些地方不太理想,为此本 ...

随机推荐

  1. DSO windowed optimization 代码 (2)

    3 非 Schur Complement 部分信息计算 参考<DSO windowed optimization 公式>,非Schur Complement 部分指 \(H_{XX}\) ...

  2. SILC超像素分割算法详解(附Python代码)

    SILC算法详解 一.原理介绍 SLIC算法是simple linear iterative cluster的简称,该算法用来生成超像素(superpixel) 算法步骤: 已知一副图像大小M*N,可 ...

  3. Django开发笔记三

    Django开发笔记一 Django开发笔记二 Django开发笔记三 Django开发笔记四 Django开发笔记五 Django开发笔记六 1.基于类的方式重写登录:views.py: from ...

  4. python 历险记(三)— python 的常用文件操作

    目录 前言 文件 什么是文件? 如何在 python 中打开文件? python 文件对象有哪些属性? 如何读文件? read() readline() 如何写文件? 如何操作文件和目录? 强大的 o ...

  5. GCC制作动态库导出符号表【转】

    转自:https://blog.csdn.net/whb_fei/article/details/76974543 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.cs ...

  6. DMA内存申请--dma_alloc_coherent 及 寄存器与内存【转】

    转自:https://blog.csdn.net/ic_soc_arm_robin/article/details/8203933 在项目驱动过程中会经常用到dma传输数据,而dma需要的内存有自己的 ...

  7. Linux Samba服务主配文件smb.conf中文详解【转】

    转自:https://blog.csdn.net/maotianwang/article/details/52524732 从网上找到描述比较详细的smb.conf中文解释: 服务名:smb 配置目录 ...

  8. 13-JS中的面向对象

    创建对象的几种常用方式 1.使用Object或对象字面量创建对象 2.工厂模式创建对象 3.构造函数模式创建对象 4.原型模式创建对象 1.使用Object或对象字面量创建对象 JS中最基本创建对象的 ...

  9. 洛谷P1970 花匠

    传送门 首先可以知道,如果一个序列是连续上升的,那么只需要取这一个序列中最高的元素即可,因为取其它的不能保证大于后面的.连续下降的序列同理.而这些恰好就是波峰和波谷. 所以遇到 $ j $ 比之前的 ...

  10. php和NodeJs共存的开发环境

    1 折腾 php nodejs 到一起 nodejs当然很火,就像着火了一样,但是必须承认要搭建一个前端的demo开发环境还是PHP靠谱, windows下可以非常的集成套件,比如http://www ...