参考:https://blog.csdn.net/a13627210064/article/details/82348059

参考:https://blog.csdn.net/u010288264/article/details/55260237     (1 2 3 4)

依賴:

<repositories><!-- 代码库 -->
<repository>
<id>maven-ali</id>
<url>http://maven.aliyun.com/nexus/content/groups/public//</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
</repository>
</repositories> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency> <!-- <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency> --> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency> </dependencies>

yml 配置连接

spring:
rabbitmq:
# host: 192.168.18.129
addresses: 192.168.18.129:
username: guest
password: guest
# 支持发布确认
publisher-confirms: true
# 支持发布返回
publisher-returns: true
listener:
simple:
# 监听的最小线程数
concurrency:
# 监听的最大线程数
max-concurrency:
retry:
enabled: true
# ack应答改模式:auto-自动,manual-手动,none-无应答
acknowledge-mode: auto

生产者:发送消息

方式一:derict

配置:

package com.icil.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; //@Configuration
public class RabbitConfig {
/********************************direct****************************************/
// 交换机定义,这里我使用的是direct类型。大家可以根据自己的业务需求来指定对应的。下面会讲几种交换机的类型
// 对应的3个参数1.交换机名称 2.持久性保持标识 3.是否自动删除标识
@Bean
public DirectExchange directExchange() {
return new DirectExchange("name", false, false);
} //创建一个队列
@Bean(name = "queue")
public Queue queue() {
return QueueBuilder.durable("name").build();
} //绑定队列到交换机上--with对应的是direct指定的具体key。
@Bean
public Binding binding(@Qualifier("queue") Queue queue,@Qualifier("directExchange") DirectExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("key"); } //
// /********************************topic****************************************/
//
//
// @Bean
// public TopicExchange topicExchange() {
// /**
// * TopicExchangeName
// * 是否持久化
// * 是否自动删除
// */
// return new TopicExchange("topicExchange", true, false);
// }
//
// /**
// * 创建一个队列,指定一个Exchange
// * @return
// */
// @Bean(name = "topicQueue")
// public Queue topicQueue() {
// return QueueBuilder.durable("topicExchange").build();
// }
//
//
// @Bean
// public Binding bindingtopic(@Qualifier("topicQueue") Queue queue, DirectExchange exchange) {
// return BindingBuilder.bind(queue).to(exchange).with("A.B.C"); } }

发送消息:

package com.icil.rabbitmq;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ConfirmCallback;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ReturnCallback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import lombok.extern.slf4j.Slf4j;
@Component
@Slf4j
public class RabbitProducer implements ConfirmCallback , ReturnCallback{ private static Logger log =LoggerFactory.getLogger(RabbitProducer.class); @Autowired
private RabbitTemplate rabbitTemplate; /** * 初始化确认发送回调及发送返回回调 */
@PostConstruct
public void init(){
rabbitTemplate.setConfirmCallback(this);
rabbitTemplate.setReturnCallback(this);
} /**
* 实现消息发送到RabbitMQ交换器后接收ack回调
* @param correlationData
* @param ack
* @param cause
*/
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) { if (ack){
// 发送成功
log.info("trainLink message send success ---"+System.currentTimeMillis() );
} else { // 发送失败
log.error("trainLink message send failed because ---" + cause);
}
} /**
* * 实现消息发送到RabbitMQ交换器,但无相应队列与交换器绑定时的回调
* * @param message
* * @param replyCode
* * @param replyText
* * @param exchange
* * @param routingKey
*/
@Override
public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
// log.error(message.getMessageProperties().getCorrelationIdString() + " send failed:error code " + replyCode + "mains:" + replyText);
log.error(message.getMessageProperties().getClusterId() + " send failed:error code " + replyCode + "mains:" + replyText); } /**
* * 发送消息,供外部调用
* * ****** 重要 ******说明:发送时的方法选择
* * ****** 重要 ******convertAndSend属于不要求返回确认的
* * ****** 重要 ******convertSendAndReceive要求返回确认
* * ****** 重要 ******大家根据不同的业务场景进行选择,
* * 不返回确认可以理解为全异步;
* * 返回确认可以理解为异步处理,同步返回,存在一个生产者等待消费者的问题
* * 选择的原则一般为一致性要求较强的,要确认返回;
* * 一致性不强的,使用不返回确认,加大处理效率,免去等待时间 */ public void sendSMSMessage(String msg){
// fanout类型的交换器不需要routingkey,我这里用的是direct所以指定了对应的routingkey
this.rabbitTemplate.convertAndSend("name", "key", msg);
// this.rabbitTemplate.convertSendAndReceive(msg);
// this.rabbitTemplate.converandre
} // public static void main(String[] args) {
// RabbitProducer rabbitProducer = new RabbitProducer();
// rabbitProducer.sendSMSMessage("just for test");
// } }

方式二  : topic

配置:

package com.icil.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; @Configuration
public class RabbitConfig2 { /********************************topic****************************************/ @Bean
public TopicExchange topicExchange() {
/**
* TopicExchangeName
* 是否持久化
* 是否自动删除
*/
return new TopicExchange("topicExchange", true, false);
} /**
* 创建一个队列,指定一个Exchange
* @return
*/
@Bean
public Queue topicQueue01() {
return QueueBuilder.durable("topicExchange01").build();
} @Bean
public Queue topicQueue02() {
return QueueBuilder.durable("topicExchange02").build();
} @Bean
public Binding binding() {
return BindingBuilder.bind(topicQueue01()).to(topicExchange()).with("A.#");
}
@Bean
public Binding binding2() {
return BindingBuilder.bind(topicQueue02()).to(topicExchange()).with("#.B.#");
} // @Bean
// public Binding bindingtopic(@Qualifier("topicQueue") Queue queue, DirectExchange exchange) {
// return BindingBuilder.bind(queue).to(exchange).with("A.B.C"); } }

发送消息

package com.icil.rabbitmq;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ConfirmCallback;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ReturnCallback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import lombok.extern.slf4j.Slf4j;
@Component
@Slf4j
public class RabbitProducer002 implements ConfirmCallback , ReturnCallback{ private static Logger log =LoggerFactory.getLogger(RabbitProducer002.class); @Autowired
private RabbitTemplate rabbitTemplate; /** * 初始化确认发送回调及发送返回回调 */
@PostConstruct
public void init(){
rabbitTemplate.setConfirmCallback(this);
rabbitTemplate.setReturnCallback(this);
} /**
* 实现消息发送到RabbitMQ交换器后接收ack回调
* @param correlationData
* @param ack
* @param cause
*/
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) { if (ack){
// 发送成功
log.info("trainLink message send success################## 888---"+System.currentTimeMillis() ); log.info("cause is################## ---",cause );
} else { // 发送失败
log.error("trainLink message send failed because ---" + cause);
}
} /**
* * 实现消息发送到RabbitMQ交换器,但无相应队列与交换器绑定时的回调
* * @param message
* * @param replyCode
* * @param replyText
* * @param exchange
* * @param routingKey
*/
@Override
public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) { log.info("$$$$$$$$$$$$$$$$$$$$$$$ message is {} $$$ replyCode is {} $$$ replyText is {} $$$ exchange is {} $$$ and routingKey is {}",message,replyCode, replyText,exchange,routingKey);
// log.error(message.getMessageProperties().getCorrelationIdString() + " send failed:error code " + replyCode + "mains:" + replyText);
log.error(message.getMessageProperties().getClusterId() + " send failed:error code " + replyCode + "mains:" + replyText); } /**
* * 发送消息,供外部调用
* * ****** 重要 ******说明:发送时的方法选择
* * ****** 重要 ******convertAndSend属于不要求返回确认的
* * ****** 重要 ******convertSendAndReceive要求返回确认
* * ****** 重要 ******大家根据不同的业务场景进行选择,
* * 不返回确认可以理解为全异步;
* * 返回确认可以理解为异步处理,同步返回,存在一个生产者等待消费者的问题
* * 选择的原则一般为一致性要求较强的,要确认返回;
* * 一致性不强的,使用不返回确认,加大处理效率,免去等待时间 */ public void sendSMSMessage(String msg){
// fanout类型的交换器不需要routingkey,我这里用的是direct所以指定了对应的routingkey
this.rabbitTemplate.convertAndSend("topicExchange", "A.B.key", msg);
} }

/*********************************************************************/

接受消息: (依赖与上面一样,无需其他配置)

  配置yml  

spring:
rabbitmq:
# host: 192.168.18.129
addresses: 192.168.18.129:
username: root
password: root
# 支持发布确认
publisher-confirms: true
# 支持发布返回
publisher-returns: true
listener:
simple:
# 监听的最小线程数
concurrency:
# 监听的最大线程数
max-concurrency:
retry:
enabled: true
# ack应答改模式:auto-自动,manual-手动,none-无应答
acknowledge-mode: auto

接收消息:(使用注解 --也可不用,此处用注解)

方式一:注解  可以参考 :https://www.jianshu.com/p/382d6f609697

package com.icil.rabbitmq;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component; import com.rabbitmq.client.Channel; @Component
public class RabbitMQConsumer {
private static Logger log =LoggerFactory.getLogger(RabbitMQConsumer.class);
/**
* * 消费者处理接收消息方法 *
* <p>
* * ****重要说明***** * 如果生产者是以convertSendAndReceive方法发送,则一定要手动给予返回,处理完后加入下面这一行: *
* ack-true处理:channel.basicAck(message.getMessageProperties().getDeliveryTag(),
* false); * 参数说明-------消息id,fasle代表不批量处理(批量是指将消息id小于当前id的都处理掉) *
* ack-false处理:channel.basicNack(message.getMessageProperties().getDeliveryTag(),
* false, false); *
* 参数说明-------消息id,fasle代表不批量处理(批量是指将消息id小于当前id的都处理掉),第二个false表示不重新入队(重新入队用true)
* * 拒绝消息:channel.basicReject(message.getMessageProperties().getDeliveryTag(),
* false); 消息不会重新入队 * 参数说明-------消息id,fasle表示不重新入队(重新入队用true) *
* 如果不手动返回,则该消息会一直认为没有被消费掉,会一直占用rabbitmq内存空间,时间一久,必然造成内存溢出,切记!!! * * @param msg
* * @param message * @param channel * @throws Exception
*/ //支持自动声明绑定,声明之后自动监听队列的队列,此时@RabbitListener注解的queue和bindings不能同时指定,否则报错
// @RabbitListener(bindings ={@QueueBinding(value = @Queue(value = "q5",durable = "true"),
// exchange =@Exchange(value = "zhihao.miao.exchange",durable = "true"),key = "welcome")}) // @RabbitListener(queues = "name")
// @RabbitListener(queues = {"name","topicExchange01","topicExchange02"})
// public void handler(String msg, Message message, Channel channel) throws Exception {
// try {
// System.out.println("$$$$$$$$$$$$$$$$$$$$$$"+msg);
// } catch (Exception e) {
// log.error(e.toString(), e);
// channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
// }
// } @RabbitListener(queues = {"topicExchange01"})
public void handler1(String msg, Message message, Channel channel) throws Exception {
try {
System.out.println("$$$$$$$$$$ topicExchange01 $$$$$$$$$$$$"+msg);
} catch (Exception e) {
log.error(e.toString(), e);
channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
}
} @RabbitListener(queues = {"topicExchange02"})
public void handler2(String msg, Message message, Channel channel) throws Exception {
try {
System.out.println("$$$$$$$$$$ topicExchange02 $$$$$$$$$$$$"+msg);
} catch (Exception e) {
log.error(e.toString(), e);
channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
}
} @RabbitListener(queues = {"name"})
public void handler3(String msg, Message message, Channel channel) throws Exception {
try {
System.out.println("$$$$$$$$$$ name $$$$$$$$$$$$"+msg);
} catch (Exception e) {
log.error(e.toString(), e);
channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
}
} }

方式二手动配置

package com.icil.config;

import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import com.rabbitmq.client.Channel;
@Configuration
public class Rabbitconfing { @Bean
public CachingConnectionFactory connectionFactory(){
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses("192.168.18.129:5672");
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
connectionFactory.setVirtualHost("/");
connectionFactory.setPublisherConfirms(true); //必须要设置
return connectionFactory;
} @Bean
public TopicExchange topicExchange() {
/**
* TopicExchangeName
* 是否持久化
* 是否自动删除
*/
return new TopicExchange("topicExchange", true, false);
} @Bean
public Queue topicQueue01() {
return QueueBuilder.durable("topicExchange01").build();
} @Bean
public Queue topicQueue02() {
return QueueBuilder.durable("topicExchange02").build();
} // @Bean
// public Binding binding() {
// return BindingBuilder.bind(topicQueue01()).to(topicExchange()).with("A.key");
// }
// @Bean
// public Binding binding2() {
// return BindingBuilder.bind(topicQueue02()).to(topicExchange()).with("B.C");
// }
// @Bean
public SimpleMessageListenerContainer messageContainer() {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory()); container.setQueues(topicQueue01());
container.setExposeListenerChannel(true);
container.setMaxConcurrentConsumers();
container.setConcurrentConsumers();
container.setAcknowledgeMode(AcknowledgeMode.AUTO); //设置确认模式手工确认
container.setMessageListener(new ChannelAwareMessageListener() {
@Override
public void onMessage(Message message, Channel channel) throws Exception {
byte[] body = message.getBody();
System.out.println("¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥receive msg queue: " + new String(body));
// Thread.sleep(10000); channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); //确认消息成功消费 } });
return container;
} @Bean
public SimpleMessageListenerContainer messageContainer2() {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory());
container.setQueues(topicQueue02());
container.setExposeListenerChannel(true);
container.setMaxConcurrentConsumers();
container.setConcurrentConsumers();
container.setAcknowledgeMode(AcknowledgeMode.MANUAL); //设置确认模式手工确认
container.setMessageListener(new ChannelAwareMessageListener() {
@Override
public void onMessage(Message message, Channel channel) throws Exception {
byte[] body = message.getBody();
System.out.println("¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥key: " + new String(body));
// Thread.sleep(10000);
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); //确认消息成功消费 }
});
return container;
} }

springboot整合ribbitMQ的更多相关文章

  1. spring-boot整合mybatis(1)

    sprig-boot是一个微服务架构,加快了spring工程快速开发,以及简便了配置.接下来开始spring-boot与mybatis的整合. 1.创建一个maven工程命名为spring-boot- ...

  2. SpringBoot整合Mybatis之项目结构、数据源

    已经有好些日子没有总结了,不是变懒了,而是我一直在奋力学习springboot的路上,现在也算是完成了第一阶段的学习,今天给各位总结总结. 之前在网上找过不少关于springboot的教程,都是一些比 ...

  3. springboot整合mq接收消息队列

    继上篇springboot整合mq发送消息队列 本篇主要在上篇基础上进行activiemq消息队列的接收springboot整合mq发送消息队列 第一步:新建marven项目,配置pom文件 < ...

  4. springboot整合mybaits注解开发

    springboot整合mybaits注解开发时,返回json或者map对象时,如果一个字段的value为空,需要更改springboot的配置文件 mybatis: configuration: c ...

  5. SpringBoot整合Redis、ApachSolr和SpringSession

    SpringBoot整合Redis.ApachSolr和SpringSession 一.简介 SpringBoot自从问世以来,以其方便的配置受到了广大开发者的青睐.它提供了各种starter简化很多 ...

  6. SpringBoot整合ElasticSearch实现多版本的兼容

    前言 在上一篇学习SpringBoot中,整合了Mybatis.Druid和PageHelper并实现了多数据源的操作.本篇主要是介绍和使用目前最火的搜索引擎ElastiSearch,并和Spring ...

  7. SpringBoot整合Kafka和Storm

    前言 本篇文章主要介绍的是SpringBoot整合kafka和storm以及在这过程遇到的一些问题和解决方案. kafka和storm的相关知识 如果你对kafka和storm熟悉的话,这一段可以直接 ...

  8. SpringBoot整合SpringCloud搭建分布式应用

    什么是SpringCloud? SpringCloud是一个分布式的整体解决方案.SpringCloud为开发者提供了在分布式系统中快速构建的工具,使用SpringCloud可以快速的启动服务或构建应 ...

  9. SpringBoot整合RabbitMQ-整合演示

    本系列是学习SpringBoot整合RabbitMQ的练手,包含服务安装,RabbitMQ整合SpringBoot2.x,消息可靠性投递实现等三篇博客. 学习路径:https://www.imooc. ...

随机推荐

  1. CTF-练习平台-Misc之 Convert

    十八.Convert 打开后发现是01代码,转换为16进制代码如下 将代码复制到winhex里面发现是rar文件,保存 打开后发现里面有个图片 解压后在图片的属性里发现一段base64代码,对其解密 ...

  2. <ul><li>

    ☆ <ul><li> 1. li是不能单独使用,必须在于ul之中的. 2. ul是块级元素,能直接定义宽高,而li是行级元素,不能直接定义 高. 3. li组 只能写在ul之中 ...

  3. test20180919 区间最大值

    题意 分析 我们将所有修改操作的左右端点都拿出来混合着排序. 然后扫描线一样扫描每个端点,维护一个堆储存当前最大值,然后就可以把这些修改操作分成O(m) 个不相交的区间,各自贡献独立. 复杂度为\(O ...

  4. day25 python学习 继承,钻石继承 多态

    ---恢复内容开始--- 通过一个列子认识父类和子类中,子类的如何实现对父类默认属性调用,同时拥有自己的属性,如何在子类中调用父类的方法,class Ainmal: country='afdas' d ...

  5. prisma 集成 pipelinedb测试

    pipelinedb 是一个基于pg数据库开发的stream sql 数据库,和prisma 集成起来可以开发很 方便的stream 应用 使用docker 安装 项目初始化 prisma init ...

  6. 按的第一个greasemonkey插件:评论时可以粘贴啦~~

    原来的样子:如果按ctrl+V会跳出错误

  7. spark之 spark 2.2.0 Standalone安装、wordCount演示

    说明:前提安装好hadoop集群,可参考 http://blog.csdn.net/zhang123456456/article/details/77621487 一. scala 安装 1.下载 s ...

  8. vue项目实现按需加载的3种方式:vue异步组件技术、es提案的import()、webpack提供的require.ensure()

    1. vue异步组件技术 vue-router配置路由,使用vue的异步组件技术,可以实现按需加载. 但是,这种情况下一个组件生成一个js文件. 举例如下: { path: '/promisedemo ...

  9. UOJ 188 【UR #13】Sanrd——min_25筛

    题目:http://uoj.ac/problem/188 令 \( s(n,j)=\sum\limits_{i=1}^{n}[min_i>=p_j]f(j) \) ,其中 \( min_i \) ...

  10. 转 Fiddler导出jmeter脚本

    前提条件:                1.下载安装抓包工具Fiddler                2.下载Fiddler插件,参考下载地址:http://download.csdn.net/ ...