首先我们在消费者这边(再强调一遍我这里建议大家消费者和生产者分两个项目来做,包括我自己便是这样的,虽然一个项目也可以,我以为分开的话随意马虎理解一点)
设置一下确认为手动确认:
当然我们要对我们的消费者监听器进行一定的配置的话,我们须要先实例一个监听器的Container 也便是容器,那么我们的监听器(一个消费者里面可以实例多个监听器)可以指定这个容器那么我们只须要对这个Container(容器)进行配置就可以了

首先得声明一个容器并且在容器里面指定确认为手动确认:AcknowledgeMode关于这个类便是一个大略的列举类我们来看看:
AcknowledgeMode关于这个类便是一个大略的列举类我们来看看:
3个状态不确认手动确认自动确认
我们刚刚配置的便是中间那个手动确认既然现在是手动确认了
那么我们在处理完这条之后得使这条确认:
正常情形下的效果,我就不演示给大家看了,这里给大家看一个如果忘却退回的效果:
这里我把确认的代码注释掉:
然后调用生产者发送一条我们来扼守理页面:
这里能看到有一条在rabbitmq当中而且状态是ready
然后我们利用消费者来消费掉他把稳这里我们故意没有见告rabbitmq我们消费成功了来看看效果
这里消费的结果打印就不截图了还是来扼守理页面:
就算我们消费端消费了下次但是能看到这条还是会在rabbitmq当中只是他的状态为 unacked 便是未确认
这便是我们刚刚说的那种情形无论消费成功与否一定要关照rabbitmq 不然就会这样一贯囤积在rabbitmq当中直到连接断开为止.
预取扯完确认我们来讲一下刚刚所说的批量处理的问题
什么情形下会碰着批量处理的问题呢?
在这里就要先扯一下rabbitmq的发放机制了
rabbitmq 默认他会最快以轮询的机制吧行列步队所有的发送给所有客户端(如果没确认的话他会添加一个Unacked的标识上图已经看过了)
那么这种机制会有什么问题呢,对付Rabbitmq来讲这样子能最快速地使自己不会囤积而对性能造成影响,但是对付我们全体系统来讲,这种机制会带来很多问题,比如说我一个行列步队有2个人同时在消费,而且他们处理能力不同,我打个最大略的比方有100个订单须要处理(消费)现在有消费者A 和消费者B ,消费者A消费一条的速率是 10ms 消费者B 消费一条的速率是15ms (当然这里只是打比方)那么 rabbitmq 会默认给消费者A B 一人50条让他们消费但是消费者A 他500ms 就可以消费完所有的并且处于空闲状态而消费者B须要750ms 才能消费完如果从性能上来考虑的话这100条消费完的韶光一共是750ms(由于2个人同时在消费)但是如果在消费者A消费完的时候能把这个空闲的性能用来和B一起消费剩下的信息的话,那么这处理速率就会快非常多。
这个例子可能有点抽象,我们通过代码来演示一下
我往Rabbitmq生产100条由2个消费者来消费个中我们让一个消费者在消费的时候休眠0.5秒(仿照处理业务的延迟)其余一个消费者正常消费我们来看看效果:
正常的那个消费者会一瞬间吧所有(50条)全部消费完(由于我们打算机处理速率非常快)下图是加了延迟的消费者:
可能我条记里面你看不出效果,这个你自己测试就会创造个中一个消费者很快就处理完自己的了其余一个消费者还在逐步的处理实在这样严重影响了我们的性能了。
实在讲了这么多那如何来办理这个问题呢?
我刚刚阐明过了造成这个缘故原由的根本便是rabbitmq的发放机制导致的,那么我们现在来讲一下办理方案: 预取
什么是预取?讲白了以前是rabbitmq一股脑吧所有都均发给所有的消费者(不管你受不受得了)而现在是在我消费者消费之前先见告rabbitmq 我一次能消费多少数据等我消费完了之后见告rabbitmq rabbitmq再给我发送数据
在代码中如何表示?
在利用预取前要把稳一定要设置为手动确认,缘故原由参考上面划重点的那句话。
由于我们刚刚设置过了这里就不贴代码了,完了之后设置一下我们预取消息的数量一样是在容器(Container)里面设置:
那么设置完之后是什么效果呢?还是刚刚那个例子还是2个消费者由于会在消费者返回的确认之后 rabbitmq才会连续发送给客户端而且客户真个累计量不会超过我们刚刚设置预取的数量,以是我们再运行同样的例子的话会创造 A消费者消费完99条了 B消费者才消费1条(由于B消费者休眠了0.5秒才消费完{返回确认} 但是0.5秒之内A消费者就已经把所有消费完毕了当然如果打算机处理速率较慢这个结果可能会有差异,效果大概便是A消费者会处理大量)
我这里的效果便是B消费者只消费一条 A消费者就消费完了,效果图就不发了这里同学们只管即便自己测试一下或者改变一下参数看看效果。
关于这个预取的数量如何设置呢?我们创造如果设置为1 能极大的利用客户真个性能(我消费完了就可以赶紧消费下一条不会导致忙得很忙闲得很闲)但是,我们每消费一条就要关照一次rabbitmq 然后再取出新的,这样对付rabbitmq的性能来讲是非常不合理的以是这个参数要根据业务情形设置
我根据我查阅到的资料然后加以测试,这个数值的大小与性能成正比但是有上限,与数据可靠性,以及我们刚刚所说的客户真个利用率成反频年夜概如下图:
那么批量确认,便是对付我们预取的,进行统一的确认。
去世信交流机我们来看一段代码:
channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
我们上面阐明过这个代码是处理失落败的确认然后第三个参数我有阐明过是是否返回到原行列步队,那么问题来了,如果没有返回给原行列步队那么这条就被作废了?
rabbitmq考虑到了这个问题供应理解决方案:去世信交流机(有些人可能叫作垃圾回收器,垃圾交流机等)
去世信交流机有什么用呢?在创建行列步队的时候可以给这个行列步队附带一个交流机,那么这个行列步队作废的就会被重新发到附带的交流机,然后让这个交流机重新路由这条
理论是这样,代码如下:
大概是这样的一个效果:
实在我们刚刚创造所谓去世信交流机,只是对应的行列步队设置了对应的交流机是去世信交流机,对付交流机来讲,他还是一个普通的交流机。
下面会列出rabbitmq的常用配置:
行列步队配置: