RabbitMQ详解:
AMQP:Advanced Message Queuing Protocol,一个统一提供统一消息服务的应用层标准高级消息队列协议;
RabbitMQ概念:
虚拟主机:一个虚拟主机持有一组交换机、队列和绑定,使用虚拟主机来进行权限控制;
交换机:Exchange用于转发消息,但是不会存储,会发送到对应的队列,根据路由;
绑定:交换机和队列的关系绑定;
队列:存储和传输消息
交换机:
Direct模式:默认的模式,先匹配再投送,设置绑定的key
Topic模式:根据通配符来发送和消费消息;和配置logStash的时候类似
Headers模式:也是根据规则匹配,有自定义匹配规则的类型,也是在绑定的时候设置
Fanout模式:消息的广播模式,会发送给所有绑定的队列;
==============================================================================
发送消息源码跟踪:
核心类RabbitTemPlate:
一些必要属性:如交换机,路由键,对列命,消息转换类,编码集以及消息发送确认ConfirmCallBack和返回确认的类ReturnCallBack,还有重试的类
发送消息时,调用convertAndSend方法,有很多重载,\
调用send方法
调用execute方法前调用doSend方法发送消息
CorrelationData对象贯穿全程 为发送消息流程的唯一ID
核心方法是channel.basicPublish();由PublisherCallbackChannelImpl利用代理类ChannelN来发送
最后追到AMQCommond类,之后的代码有兴趣先不看
发送完消息之后
判断通道的事务是由自己管理还是有外部事务协调器管理,如果是外部管理 需要二次提交
===============================================================================
消费消息
配置文件中配置监听器
参数有默认的消费者方法名,编码集以及消息转换器,以及路由键,以及一个Object消费者代理类
根据配置会调用构造方法
设置默认的消息转换器
设置代理类
此监听器需要一个容器去执行
SimpleMessageListenerContainer继承AbstractMessageListenerContainer继承RabbitAccessor并实现了smartlifecycle接口
在Spring上下文的refresh方法中会执行实现了InitializingBean的bean的afterPropertiesSet方法, AbstractMessageListenerContainer实现了InitializingBean,在此方法中会初始化,
校验配置,在子类实现
初始化
初始化消费者与通道的关系
初始化代理类
初始化完成之后为啥不把父类的属性设置成true? 而是在Spring初始化完成之后调用lifecycle的start方法中判断是否初始化完毕
子类重写的dostart方法
初始化所有的消费者,将属性都设置好,返回数量
异步执行将消费者包装AsyncMessageProcessingConsumer线程类,并使用CountDownLatch锁挨个执行
核心代码,调用reviceAndExecute方法,其中
开始执行监听器
最终调用AOP代理类的
核心代码
InvokeListenerMethod 执行方法得到结果
根据监听器的结果返回响应
整个过程完成!