前面的学习都是基于原生的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. Problem F Plug It In!

    题目链接:https://cn.vjudge.net/contest/245468#problem/F 大意:给你插座和电器的对应关系,有多个电器对应一个插座的情况,但是一个插座只能供一个电器使用,现 ...

  2. mysql一次查询,返回多个统计结果

    1.sum(if) select sum(if(status=1,1,0)) as s1_count,sum(if(status=2,1,0)) as s2_countfrom order; 2.co ...

  3. 一步步使用Code::Blocks进行设置断点调试程序

    一.调试之前要做的工作 首先,我们要确保Code::Blocks的配置正确,调试工作才能进行得更顺利 为此,我们需要生成调试符号.调试符号可以让调试器知道代码的哪一行正在执行,这样你就可以知道程序运行 ...

  4. POST 上传 JSON 数据

    // // ViewController.m // 03-post上传json // // Created by jerry on 15/10/10. // Copyright (c) 2015年 j ...

  5. Struts S2-052漏洞利用

    昨天在FreeBuf上看到[9月6日更新]漏洞预警 | 高危Struts REST插件远程代码执行漏洞(S2-052) 然而一直复现不了,今天又试了下竟然成功了. 由于水表查的较严,就不冒险搞别人的服 ...

  6. Latex graphicx 宏包 scalebox命令

    scalebox  命令需要加载  \usepackage{graphicx} \scalebox{水平缩放因子}[垂直缩放因子]{对象} \scalebox 命令对其作用的对象进行缩放,使缩放后的对 ...

  7. ubuntu “下列的软件包有不能满足的依赖关系” 问题

    前阵子,刚安装Ubuntu时,安装vim的问题,现在些出来分享一下. apt-get install vim 正在读取软件包列表... 完成 正在分析软件包的依赖关系树 正在读取状态信息... 完成 ...

  8. 基于theano的降噪自动编码器(Denoising Autoencoders--DA)

    1.自动编码器 自动编码器首先通过下面的映射,把输入 $x\in[0,1]^{d}$映射到一个隐层 $y\in[0,1]^{d^{'}}$(编码器): $y=s(Wx+b)$ 其中 $s$ 是非线性的 ...

  9. python魔法方法:__getattr__,__setattr__,__getattribute__

    python魔法方法:__getattr__,__setattr__,__getattribute__ 难得有时间看看书....静下心来好好的看了看Python..其实他真的没有自己最开始想的那么简单 ...

  10. mac 报错Root chmod operation not permitted on file

    系统:mac os 10.14.1 重启电脑 mac用户在升级系统之后,电脑启用了SIP(System Integrity Protection),增加了rootless机制,导致即使在root权限下 ...