原理场景

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的使用的更多相关文章

  1. 分布式系统之消息中间件rabbitmq

    分布式系统之消息中间件rabbitmq 博客分类: 感谢:  一般php 用rabbitmq  java 用activemq  http://spartan1.iteye.com/blog/11802 ...

  2. 分布式系统消息中间件——RabbitMQ的使用基础篇

    分布式系统消息中间件——RabbitMQ的使用基础篇

  3. 分布式系统消息中间件——RabbitMQ的使用思考篇

    分布式系统消息中间件--RabbitMQ的使用思考篇 前言     前面的两篇文章分布式系统消息中间件--RabbitMQ的使用基础篇与分布式系统消息中间件--RabbitMQ的使用进阶篇,我们简单介 ...

  4. 分布式系统消息中间件——RabbitMQ的使用进阶篇

    分布式系统消息中间件--RabbitMQ的使用进阶篇 前言     上一篇文章 (https://www.cnblogs.com/hunternet/p/9668851.html) 简单总结了分布式系 ...

  5. 消息中间件——RabbitMQ(一)Windows/Linux环境搭建(完整版)

    前言 最近在学习消息中间件--RabbitMQ,打算把这个学习过程记录下来.此章主要介绍环境搭建.此次主要是单机搭建(条件有限),包括在Windows.Linux环境下的搭建,以及RabbitMQ的监 ...

  6. 消息中间件——RabbitMQ(三)理解RabbitMQ核心概念和AMQP协议!

    前言 本章学习,我们可以了解到以下知识点: 互联网大厂为什么选择RabbitMQ? RabbiMQ的高性能之道是如何做到的? 什么是AMQP高级协议? AMQP核心概念是什么? RabbitMQ整体架 ...

  7. 消息中间件——RabbitMQ(四)命令行与管控台的基本操作!

    前言 在前面的文章中我们介绍过RabbitMQ的搭建:RabbitMQ的安装过以及各大主流消息中间件的对比:,本章就主要来介绍下我们之前安装的管控台是如何使用以及如何通过命令行进行操作. 1. 命令行 ...

  8. 消息中间件——RabbitMQ(五)快速入门生产者与消费者,SpringBoot整合RabbitMQ!

    前言 本章我们来一次快速入门RabbitMQ--生产者与消费者.需要构建一个生产端与消费端的模型.什么意思呢?我们的生产者发送一条消息,投递到RabbitMQ集群也就是Broker. 我们的消费端进行 ...

  9. 消息中间件——RabbitMQ(六)理解Exchange交换机核心概念!

    前言 来了解RabbitMQ一个重要的概念:Exchange交换机 1. Exchange概念 Exchange:接收消息,并根据路由键转发消息所绑定的队列. 蓝色框:客户端发送消息至交换机,通过路由 ...

  10. 消息中间件——RabbitMQ(七)高级特性全在这里!(上)

    前言 前面我们介绍了RabbitMQ的安装.各大消息中间件的对比.AMQP核心概念.管控台的使用.快速入门RabbitMQ.本章将介绍RabbitMQ的高级特性.分两篇(上/下)进行介绍. 消息如何保 ...

随机推荐

  1. vue2.0和animate.css的结合使用

    animate.css是一款前端动画库,相似的有velocity-animate. 上述是一个完整的结构.其中重要的几个点用箭头表示出来.首先在transition组件内部,需要定义两个基本的clas ...

  2. react用高阶组件实现路由守卫

    react-router不像vue-router一样有很多钩子函数,可以做路由守卫.想实现路由守卫,可以用高阶组件来实现. @connect(state => ({ isLogin: state ...

  3. 基于【 springBoot +springCloud+vue 项目】二 || 后端框架详解

     前言 在上一篇中,我们搭建了一个-API服务提供接口模块,目的为了提供了消费方进行调用.为什么不直接在service层直接提供调用接口,而是重新创建一个接口层模块?首先我们需要对Feign有所了解. ...

  4. python小知识-sys.argv

    sys.argv 就是一个从程序外部获取参数的桥梁 1.t1.py import sys a = sys.argv b = len(sys.argv) print(a) print(b) 在pytho ...

  5. flutter主题颜色

    主题色 右下角的FloatingActionButton的颜色就是默认取值MaterialColor, 默认是蓝色的,如果修改成primarySwatch,就会变成这个颜色值. 一.primarySw ...

  6. UART串口简介

    通用异步收发传输器(Universal Asynchronous Receiver Transmitter) 原理 发送数据时,CPU将并行数据写入UART,UART按照一定的格式在一根电线上串行发出 ...

  7. jqGrid TreeGrid 加载数据 排序 扩展

    发现 jqGrid TreeGrid 加载的数据必须要排序 给了两种平滑数据模式尽然不内部递归 所以改了下源码加了个数据二次过滤器扩展 数据本该是这样的 结果没排序成这样了 (而且还得是从根节点到子节 ...

  8. STM32L1xx——sx1278开发之LoRa扩频技术基础知识

    扩频技术的发现 1944年,好莱坞26岁女影星HedyLamarr(号称世界上最美丽的女人)发明了扩频通信技术,这种跳频技术可以有效地抗击干扰和实现加密. 后来人们发现,扩频技术可以得到如下收益:从各 ...

  9. Django项目上线的准备工作

    settings文件配置 添加上STATIC_ROOT = os.path.join(BASE_DIR, "/static/") 我的配置项目文件的最终 STATIC_URL = ...

  10. Hadoop_19_MapReduce&&Yarn运行机制

    1.YARN的运行机制 1.1.概述: Yarn集群:负责海量数据运算时的资源调度,集群中的角色主要有:ResourceManager.NodeManager Yarn是一个资源调度(作业调度和集群资 ...