消息中间件RabbitMQ的使用
原理场景
MQ在所有项目里面都很常见,
1、减少非紧急性任务对整个业务流程造成的延时;
2、减少高并发对系统所造成的性能上的影响;
举例几个场景:
1、给注册完成的用户派发优惠券、加积分、发消息等(派发优惠券、加积分、发消息这些属于非紧急性任务,可交由MQ进行处理,先让用户完成注册)
2、实时收集用户运动数据,并且收集数据后还需要比较复杂和耗时的操作才能完成业务处理(实时的数据采集任务一般并发量都是很高的,我们就应该先发送到MQ,再进行有序的处理)
另外说明一下,高并发的问题有很多种处理手段,而MQ是我认为的最稳健、简单的手段之一,所以我会优先使用
大概流程
首先用docker安装RabbitMQ,快捷
进入控制台,下图简单介绍下各个功能模块

大致流程
1、发送消息到MQ
2、MQ接收并保存消息等待消费
3、消费者有序地进行消息处理
Springboot中的使用
springboot中使用MQ超级简单
1、配置
#RabbitMq
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=test
spring.rabbitmq.password=123456
spring.rabbitmq.virtual-host=test
spring.rabbitmq.listener.simple.retry.max-attempts=5
spring.rabbitmq.listener.simple.retry.enabled=true
spring.rabbitmq.listener.simple.retry.initial-interval=5000
spring.rabbitmq.listener.simple.default-requeue-rejected=false
spring.rabbitmq.listener.simple.prefetch=1 #这个根据自己业务情况来定
2、发送
@Autowired
private AmqpTemplate amqpTemplate; @Test
public void testMq(){
User user = new User();
user.setName("cjh陈"); amqpTemplate.convertAndSend("exchange_01","que_01", JSON.toJSONString(JSONResult.SUCC("",user)));
}
3、消费
@RabbitListener(containerFactory = "containerFactory",concurrency = "10",bindings = {@QueueBinding(declare = "false",value = @Queue(value = "que_01"), exchange = @Exchange(declare = "false",value = "exchange_01",type = "fanout"))})
public void process(Message message, com.rabbitmq.client.Channel channel) {
Long deliveryTag = null;
String data = null;
try {
deliveryTag = message.getMessageProperties().getDeliveryTag();
data = new String(message.getBody(), "UTF-8");
//你的业务处理
test01(data);
} catch (Exception e) {
logger.warn("MQ异常 {} , {} , {}" , e.getMessage(),e.getCause(),data);
}finally {
logger.warn("======消息处理结束");
}
try {
channel.basicAck(deliveryTag, false); // 确认消息成功消费(配置需要开启消费确认模式)
} catch (IOException e) {
logger.warn("======MQ应答出错,请检查");
}
}
3步完成使用
特别说明几点
1、AmqpTemplate 好像做不到发布确认,要用RabbitTemplate,发布确认我主要用在分布式事务的场景
2、containerFactory可以不配置,根据实际情况来,下面再说明
3、concurrency指每个listener在初始化的时候设置的并发消费者的个数(注意是每个),如果需求是一个队列只能有一个消费者的情况可以在 @RabbitListener 里面设置 exclusive = true, concurrency = 1
简单画了一下,,,留着自己看,,

4、declare = "false",很常用,意思就是说加入你MQ控制台里面已经新建好队列或者交换机了,这里就应该配false表示程序不再进行重新定义,不然容易发生报错(当重新定义的参数与已定义的参数不一致时就会报错)
5、权限方面的处理以后再记录,,
回到上面第2点,containerFactory什么时候会用到?
某些配置需要自定义,比如线程池的大小,
当concurrency数值放大的时候,比如100,我发现大部分的消费者并没有工作,这是因为被线程池的大小所限制,网上的人说线程池大小默认是50,我也没去查估计差不多也就这个数,那么这个时候我们就需要自定义的containerFactory:
package xxx; import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.annotation.RabbitListenerConfigurer;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistrar;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* @author cjh
* @Package xxx
* @Description:
* @date: 2019/6/30 20:19
*/
@Configuration
@EnableRabbit
public class MqContainerFactory implements RabbitListenerConfigurer { /**
* containerFactory
* @Description: 自定义配置
* @param
* @return
*/
@Bean
public SimpleRabbitListenerContainerFactory containerFactory(ConnectionFactory connectionFactory) throws Exception{
SimpleRabbitListenerContainerFactory factory=new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
//必须是concurrency的两倍以上
ExecutorService service=Executors.newFixedThreadPool(200);
factory.setTaskExecutor(service);
factory.setPrefetchCount(1);
return factory;
} @Bean
public DefaultMessageHandlerMethodFactory myHandlerMethodFactory() {
DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
factory.setMessageConverter(new MappingJackson2MessageConverter());
return factory;
} @Override
public void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {
registrar.setMessageHandlerMethodFactory(myHandlerMethodFactory());
} }
记录完成
有错欢迎指正,转载请注明博客出处:http://www.cnblogs.com/cjh-notes/
消息中间件RabbitMQ的使用的更多相关文章
- 分布式系统之消息中间件rabbitmq
分布式系统之消息中间件rabbitmq 博客分类: 感谢: 一般php 用rabbitmq java 用activemq http://spartan1.iteye.com/blog/11802 ...
- 分布式系统消息中间件——RabbitMQ的使用基础篇
分布式系统消息中间件——RabbitMQ的使用基础篇
- 分布式系统消息中间件——RabbitMQ的使用思考篇
分布式系统消息中间件--RabbitMQ的使用思考篇 前言 前面的两篇文章分布式系统消息中间件--RabbitMQ的使用基础篇与分布式系统消息中间件--RabbitMQ的使用进阶篇,我们简单介 ...
- 分布式系统消息中间件——RabbitMQ的使用进阶篇
分布式系统消息中间件--RabbitMQ的使用进阶篇 前言 上一篇文章 (https://www.cnblogs.com/hunternet/p/9668851.html) 简单总结了分布式系 ...
- 消息中间件——RabbitMQ(一)Windows/Linux环境搭建(完整版)
前言 最近在学习消息中间件--RabbitMQ,打算把这个学习过程记录下来.此章主要介绍环境搭建.此次主要是单机搭建(条件有限),包括在Windows.Linux环境下的搭建,以及RabbitMQ的监 ...
- 消息中间件——RabbitMQ(三)理解RabbitMQ核心概念和AMQP协议!
前言 本章学习,我们可以了解到以下知识点: 互联网大厂为什么选择RabbitMQ? RabbiMQ的高性能之道是如何做到的? 什么是AMQP高级协议? AMQP核心概念是什么? RabbitMQ整体架 ...
- 消息中间件——RabbitMQ(四)命令行与管控台的基本操作!
前言 在前面的文章中我们介绍过RabbitMQ的搭建:RabbitMQ的安装过以及各大主流消息中间件的对比:,本章就主要来介绍下我们之前安装的管控台是如何使用以及如何通过命令行进行操作. 1. 命令行 ...
- 消息中间件——RabbitMQ(五)快速入门生产者与消费者,SpringBoot整合RabbitMQ!
前言 本章我们来一次快速入门RabbitMQ--生产者与消费者.需要构建一个生产端与消费端的模型.什么意思呢?我们的生产者发送一条消息,投递到RabbitMQ集群也就是Broker. 我们的消费端进行 ...
- 消息中间件——RabbitMQ(六)理解Exchange交换机核心概念!
前言 来了解RabbitMQ一个重要的概念:Exchange交换机 1. Exchange概念 Exchange:接收消息,并根据路由键转发消息所绑定的队列. 蓝色框:客户端发送消息至交换机,通过路由 ...
- 消息中间件——RabbitMQ(七)高级特性全在这里!(上)
前言 前面我们介绍了RabbitMQ的安装.各大消息中间件的对比.AMQP核心概念.管控台的使用.快速入门RabbitMQ.本章将介绍RabbitMQ的高级特性.分两篇(上/下)进行介绍. 消息如何保 ...
随机推荐
- WinPE基础知识之导入表
// 导入表 (结构体数组,以一个全零元素为结尾,每一个数组元素,代表一个PE文件导入信息) // 导入表存储的是从其它PE文件导入过来的函数名.序号,加载到内存之后,还存储这些函数的地址 typed ...
- Spring事务的配置、参数详情及其原理介绍(Transactional)
Spring 事务管理分为编程式和声明式的两种方式.编程式事务指的是通过编码方式实现事务:声明式事务基于 AOP,将具体业务逻辑与事务处理解耦.声明式事务管理使业务代码逻辑不受污染, 因此在实际使用中 ...
- VUE【二、选项和生命周期】
vue对象,类似于一个viewModel,是处理页面显示的数据模型的对象 其中会有很多选项,以下为较常用的: 选项 1.data-数据 vue实例会代理其data对象里的所有属性 2.methods- ...
- Oracle笔记(十) 约束
表虽然建立完成了,但是表中的数据是否合法并不能有所检查,而如果要想针对于表中的数据做一些过滤的话,则可以通过约束完成,约束的主要功能是保证表中的数据合法性,按照约束的分类,一共有五种约束:非空约束.唯 ...
- insmod: can't insert 'xxx.ko': unknown symbol in module, or unknown parameter
手动加载内核模块时候,报如下错误信息 insmod: can't insert 'xxx.ko': unknown symbol in module, or unknown parameter 问题原 ...
- Django—model系统:ORM对数据库操作
基本操作 <1> all(): 查询所有结果 <2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 <3> get(**kwargs): ...
- linux——实际工作中如何使用linux
实际工作中,linux系统都不会在我们自己的电脑上,linux系统安装在机房的服务器上,我们操作linux不可能跑到机房去,所以我们需要有一个工具,能在公司通过网络远程连接到机房的linux服务器上 ...
- Java&Python&Appium 驱动APP及Desired Capabilities配置
一.摘要 本篇博文,将阐述如何将环境&代码&APP联系起来工作 二.Java代码 我们先看一段真实的java代码,我将他放在了TestNG框架的@BeforeTest里,执行这段即可启 ...
- mpvue打小程序预览码
喂,快给我打一个小程序预览码 前端大全 昨天 (点击上方公众号,可快速关注) 来源:写Bug segmentfault.com/a/1190000015336845 需求 开发小程序的朋友们随时都会听 ...
- spring boot2X代码混淆
为了防止代码很容易被反编译而造成泄露,所以打包时进行代码混淆 使用 proguard-maven-plugin插件 <build> <finalName>${artifactI ...