为什么80%的码农都做不了架构师?>>>   

前言:包的引入

首先,我们使用的是基于spring boot的rabbitMq,

Maven地址

    <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.4.0.RELEASE</version><relativePath /></parent><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>

系统中会加入这样一个类库:

打开发现里面只有一个pom文件

打开以后我们看到:

三个jar包自上到下,分别是对Spring Boot的核心启动器(包含了自动配置、日志和YAML),为集成messaging api和消息协议提供支持,以及spring对rabbitmq的封装来支持AMQP协议

spring-rabbit提供了对RabbitMq客户端的封装。所以我们在研究spring-rabbit源码时候应该先对rabbitMq client有一个初步认识。

首先,我们将目光放在客户端client的包中,这个包定义了rabbitMq client所需要的一系列功能接口、实现类以及实际相关的操作类。

正文:

1:AMQP与AMQPImpl

AMQP接口及其实现类,定义了AMQP协议底层通讯需要的相关契约,在我使用时候可以忽略,如果对这方面有想深入可以去了解,再次我们仅列出相关代码,不在深究。

下面我们根据RabbitMq的使用流程来逐步进行分析。

2:ConnectionFactory

ConnectionFactory从名字看可以得知,它是一个用于获得Connection的工厂类。它定义了创建Connection需要的一系列默认参数,以及对参数的getter/setter方法。

常量类用于定义AMQP协议对接和系统内默认值,我们可以忽略,下面的私有变量是我们可以通过set方法进行配置的属性。这些属性直接与我们的系统配置和之后的调优相关,可以重点研究一下。

(上图为connection私有变量以及方法,此处并不完整,仅供参考)

与ConnectionFactory功能设计相关的一系列方法,对创建Connection提供了多种方法。此处我们不在深究。只要知道这个类最主要的功能——创建链接。

3:Connection

public interface Connection extends ShutdownNotifier {…}

Connection接口继承了ShutdownNotifier接口,ShutdownNotifier为连接添加一系列关闭通知的支持,包括添加关闭监听器等,在此我们可以先忽略,把目光放在Connection本身。

由上图可以看出,Connection首先定义了一系列获取相关参数的get方法。在我们需要获取参数的时候可以使用。

这个接口中最常用也最重要的两个功能:createChannel 和close。

为了解Connection我们可以看一下他的实现类:AMQConnection,忽略其他类成员,主要看一下createChannel的实现。

1:首先,它调用私有方法ensureIsOpen(),这个方法名字很有迷惑性,它并不确保Connection处于开启状态,它所做的仅仅是判断连接是否已经被打开,如果连接处于关闭状态,会直接抛出一个AlreadyClosedException。

2:然后,判断他的成员变 _channelManager是否为null。

_channelManager作为ChannelManager类的对象,用来对Connection中的Channel进行管理(通常我们不会创建多个Connection因为这是一种比较重要的资源,而每个Connection中都可以创建多个Channel。)

_channelManager用volatile标记以确保多线程的可见,它在Connection被启动时候创建并传入参数,此处规定Connection中必须包含一个初始化的ChannelManager的对象,也就是说所有Channel都必须被置于ChannelManager中管理,否则不能被成功创建。(至于_channelManager什么时候会为null,我并没有深究)。

3:最后,调用ChannelManager的createChannel方法来创建Channel.

此方法会给通道赋予一个编号(或者自定义编号),并返回Channel的实现类ChannelN。至此Channel创建完成,我们得到了一个可以用于绑定Queue的信道。

4:Channel

前文介绍的从Connection创建、启动到生成Channel这一系列动作,在我们实际应用中其实往往只需要几行代码就可以编写完成。 我们已经知道Channel相对Connection是更廉价的资源,通过对Channel进行操作,我们可以完成大部分需要的业务功能,所以这一章相对前面更重点一些。

下面,我们先预览一下Channel接口的契约,由于方法过多,且分割开来看。

getChannelNumber : 获取该channel在channelManager中的序列。

getConnection:    获取包含此channel的Connection。

Close : 关闭当前channel

flowBlocked  : 该方法已经被弃用,不深究。

abort : 中止通道, 这个方法的实现通常是调用close方法(close方法五个参数boolean abort 设置为true),与close不同的是使用abort关闭通道时,此操作中的所有异常都会被丢弃。

addReturnListener:在通道上添加一个returnListener,来处理不能发送或未被送达的消息。)如果发送时设置“强制发送”或“立即发送” ,但是消息没有被接收到,就会回returnListener。

removeReturnListener : 移除一个returnListener,注意一个Channel允许有多个returnListener,移除时需要传入被移除对象的引用。

clearReturnListeners : 清除该channel上所有returnListener (其实是调用Collection<ReturnListener>的clear() )

另外几个不同用途监听器的方法此处忽略,有需求了请自行研究。

getDefaultConsumer和setDefauletConsumer这两个方法对Channel的私有变量defaultConsumer进行操作,允许channel设置一个默认的消费者以处理某些情况,但大多数时候并不需要使用这个方法,此处不再深究。

这一系列功能应该是我们使用最多,也是最需要了解的部分了。

basicQos:拥有三个重载方法,通过basicQos为客户设置同一时间点获得消息数的最大值。

在默认状态下,RabbitMQ会按顺序得把消息发送给每个消费者(consumer)。平均每个消费者都会收到同等数量得消息(轮询)。但如果有个Consumer工作比较重,那么就会导致有的Consumer基本没事可做,有的Consumer却是毫无休息的机会。

例如:basicQos(1),这样RabbitMQ就会使得每个Consumer在同一个时间点最多处理一个Message。换句话说,在接收到该Consumer的ack前,他它不会再将新的Message分发给它。()

basicPublish : 发布消息! 这是最最重要的方法了,我们所做的一切操作都是为了消息最后的发送,这个方法含有三个重载方法,主要包含对exchange、routingKey、是否持久化、是否独占和消息主体等一系列对象引用和配置。发送消息时候需要根据实际需求进行配置。

exchangeDeclare : 声明一个交换机! 所有message都是Channel---->exchange---->queue的,调用这个方法创建一个Exchange,这里的Exchange的类型直接决定了之后的消息分发机制。

exchangeDelete : 删除交换机,当参数中的ifUnused为true时,只允许exchange为使用时被删除。

exchangeBind:绑定两个exchange,应该是将一个源交换机的消息绑定到另一个交换机(我并没有使用过这个方法,因为我还没有想到这个方法的应用场景,知道有个这个功能即可,先不深究。)

exchangeUnbind: 解除交换机的绑定,exchangeBind的反向方法,不深究。

queueDeclare:声明一个队列!重要方法,共两个重载方法。我们只看参数最多的一个。

queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete,
Map<String, Object> arguments){...}

String queue: 队列名称。

boolean durable:是否持久化,为true时,该队列将在服务器重启后仍然存在(当RabbitMQ退出时,默认会将消息和队列都清除)。

boolean exclusive:是否为独占队列,为true时,这个队列是独占队列,只被声明者使用。

boolean autoDelete:是否自动删除,为true时,服务器将在这个队列不再使用时候删除它。

Map<String, Object> arguments:队列的其他属性,即Queue实例中的arguments参数,具体作用目前我并没有使用过,通常设置为null。

queueDelete : 删除队列。对指定name的队列进行删除操作,方法中两个布尔值分别为:是否在未使用时候删除和是否在队列为空时删除。

queueBind : 队列与交换机的绑定,也是常用的方法之一。所有队列都必须与一个交换机进行绑定,从而接收消息。

queueUnbind:解除queue与exchange的绑定。

queuePurge : 清除指定队列的内容。

basicGet : 从队列上检索消息,获取一个持有消息相应数据的bean :GetResponse。

basicAck :消息确认。RabbItMQ发送了一个消息给消费者后,会马上从内存中移除这个信息。为了保证消息永远不会丢失,RabbitMQ支持消息应答。消费者发送应答给RabbitMQ,告诉它信息已经被接收和处理,然后RabbitMQ可以自由的进行信息删除。如果消费者没有发送应答,RabbitMQ会认为该信息没有被完全处理,然后将会重新转发给别的消费者。(消息应答默认是打开的),在消费者调用basicConsume方法时若设置为false,则需要调用basicAck手动返回应答

basicNack :拒绝一个或多个接收的消息

basicReject : 拒绝消息 (这两个没有看。)

客户端接收消息的模式默认是自动应答,但是通过设置autoAck为false可以让客户端主动应答消息。当客户端拒绝此消息或者未应答便断开连接时,就会使得此消息重新入队。

basicConsume : 启用消费者。消费者通常使用的基本方法,内部调用了Consumer的handleConsumeOk进行处理(通常在ConsumerDispatcher内实现),将一个Consumer的实现对象注册到Queue中。

String basicConsume(String queue, boolean autoAck, String consumerTag, boolean noLocal,boolean exclusive, Map<String, Object> arguments, Consumer callback) throws IOException{...}

String queue: 队列名称

boolean autoAck: 自动确认,为false时需要消费者调用basicAck进行显示确认

String consumerTag: 客户端生成的消费者标签,用于建立上下文。

boolean noLocal:如果不应该给此消费者传递消息,则设置为true

boolean exclusive: 是否独占

Map<String, Object> arguments : 其他配置参数

Consumer callback : 消费者对象的接口

basicCancel: 取消消费者。调用Consumer的handleCancelOk处理

basicRecover : 恢复消息。请求重新发送未确认的消息,当消费者断开连接未能及时给服务端返回消息确认时,可以调用此方法要求再次获取之前的消息。如果为true则消息将被重新排序和还可能交付给不同的消费者。 如果为false,则将消息重新发送给之前的消费者。

txSelect:在通道上开启事务,保证消息不会丢失。(和confirm模式不能同时使用,而且会带来大量的多余开销,导致吞吐量下降很多,故而不推荐。)

txConfirm:提交事务。

txRollback:回滚事务。

confirmSelect:启用通道的confirm模式。认情况下,发送端不关注发出去的消息是否被消费掉了。可设置channel为confirm模式,所有发送的消息都会被确认一次,用户可以自行根据server发回的确认消息查看状态。

getNextPublishSeqNo:查看下一个要发送的消息的序号。

waitForConfirms:等待所有消息发送并确认。

messageCount:返回队列中即将发送的消息数量。

consumerCount:返回队列中的消费者数量。

以上是channel接口定义的全部方法内容,具体实现可以查看ChannelN。

5:Consumer与QueueingConsumer

从接口的方法名可以知晓,这个接口定义了一系列消费者处理消息后的回调方法,通常我们并不直接使用这些方法。

QueueingConsumer:

nextDelivery : 等待下一个消息传递并返回。

QueueingConsumer类含有一个内部类Delivery,它抽象了一个消息实体,我们对消费者的大部分处理都是操作delivery来完成的。

_body是一个byte[],保存我们的消息主体。

_envelope是类Envelope的实例对象,它封装了一系列于AMQP的参数和方法。可以使用getEnvelope()获取当前的信息。

_properties记录了一系列与请求本身相关的基本属性,并未这些参数提供了一系列get方法,以供获取。

清单:

<完>

转载于:https://my.oschina.net/dlam/blog/807220

RabbitMQ探索:结构分析与常用方法解释相关推荐

  1. 功能连接分析方法及其解释缺陷的综述

    文章来源于微信公众号(茗创科技),欢迎有兴趣的朋友搜索关注. 本文是一篇关于功能连接分析方法及其相关注意事项的综述,于2016年发表在Frontiers in Systems Neuroscience ...

  2. 因果解释能够对规则进行解释吗?

    来源:<哲学动态>2017年第10期 作者:初维峰(西安交通大学人文社会科学学院) 本文受中国博士后科学基金面上资助项目"当代西方因果解释理论研究"(2017M6131 ...

  3. java jigsaw_Java 9,Jigsaw,JPMS和模块:个人探索

    java jigsaw Java 9由于Jigsaw项目而延迟了很多次,您可能会听到很多关于模块,模块化和其他内容的信息,那么,这到底是什么呢? 什么是模块化,模块化平台是什么意思? Java平台模块 ...

  4. Java 9,Jigsaw,JPMS和模块:个人探索

    Java 9由于Jigsaw项目而延迟了很多次,您可能会听到很多关于模块,模块化和其他内容的信息,那么,它的全部含义是什么? 模块化到底是什么,模块化平台是什么意思? Java平台模块系统(JPMS) ...

  5. RabbitMQ学习之Flow Control

    当RabbitMQ发布消息速度快于消费速度或者系统资源不足时,RabbitMQ将降低或阻断发布消息速度,以免服务器资源饱满而宕机,可以通过rabbitmqctl和web管理页面查看连接的状态为flow ...

  6. Docker搭建RabbitMQ

    RabbitMQ RabbitMQ是一个被广泛使用的开源消息队列.它是轻量级且易于部署的,它能支持多种消息协议.RabbitMQ可以部署在分布式和联合配置中,以满足高规模.高可用性的需求. Rabbi ...

  7. 消息队列:RabbitMQ

    消息队列 Message Queue 一. 消息中间件概述 1.大多应用中,可通过消息服务中间件来提升系统异步通信.扩展解耦能力 2.消息服务中两个重要概念: 消息代理(message broker) ...

  8. 探索式软件测试学习笔记

    在读了几篇<探索式测试>笔记类文章,发现对于书中的诸如"旅馆区测试类型"比喻,由于不理解前因后果,找不到关联性,有点云里雾里,遂重读原书,在原文章的基础上进行了自己的重 ...

  9. ACL'22丨预训练语言模型能否像人一样解释明喻

    每天给你送来NLP技术干货! 来自:知识工场 前言 明喻是人们日常生活中一类常见的表述形式,解释明喻可以帮助机器更好地理解自然语言.因此,明喻解释(SimileInterpretation)是自然语言 ...

最新文章

  1. ntdll.dll和ntoskrnl.exe中的NT*和ZW*函数区别
  2. Android 4.0新增Space及GridLayout初谈
  3. Netflix:为什么建立专门的媒体数据库?
  4. git与svn的区别 ?Git 与 SVN那个更好?
  5. hapi 使用 lab 和 code 进行测试
  6. VC/MFC 键盘钩子,代码片断
  7. SynchronizationContext笔记
  8. SWUST OJ Coin Changing
  9. 地图测量面积工具app_GPS地图测量尺
  10. 音频转码-Mp3转AMR--转载请注明出处
  11. MP4视频播放问题(有声音无图像)分析与解决——FFmpeg视频处理教程
  12. 一枚钻戒如何成功借势世界杯,与粉丝秀恩爱
  13. python语言属于科学计算语言吗_python语言属于( )
  14. Premiere Pro 常用快捷键
  15. 向上沟通2-冰山理论
  16. 电磁场与仿真软件(22)
  17. element-ui表格组件分页后完整导出到excel的方法
  18. 组播IP地址和MAC地址的映射关系
  19. Spring事务和MySQL事务详解面试
  20. 手机端html跑马灯效果,使用css3和js在手机上实现简单的跑马灯效果

热门文章

  1. 踢毽也能治胃病,适当的运动带来健康,健康带来快乐
  2. 手机权限的一些问题记录
  3. 一套代码小程序WebNative运行的探索01
  4. SpringSecurity-eclipse
  5. unity3d EasyTouch滑动屏幕移动相机观看场景
  6. 产品打包工具的制作,ant,编译源码,打jar包,打tag,打war包,备份release版本等...
  7. rommon模式下给路由器灌入IOS
  8. ASP.NET MVC5+EF6+EasyUI 后台管理系统(46)-工作流设计-设计分支
  9. 3.8 采购协议管理
  10. SafeNet宣布推出其最小的圣天诺HASP硬件型软件保护锁