RabbitMQ学习(二)

接上篇博客  http://blog.csdn.net/qq_15351029/article/details/78628612


三、Spring boot 整合RabbitMQ实现三种消息传递方式

参考:

http://www.cnblogs.com/web424/p/6763031.html

http://www.cnblogs.com/web424/p/6767314.html

http://www.cnblogs.com/web424/p/6767713.html

 

|Direct模式

复习一下Direct模式:

DirectExchange是RabbitMQ默认的交换机模式,也是最简单的模式,根据key全文匹配去寻找队列。

X -Q1 就有一个 binding key,名字为 orange;

X -Q2 就有 2 个 binding key,名字为 black 和 green。

当消息中的 路由键 和这个 binding key 对应上的时候,那么就知道了该消息去到哪一个队列中。
Ps:为什么 X 到 Q2 要有 black,green,2个 binding key呢,一个不就行了吗? - 这个主要是因为可能又有 Q3,而Q3只接受 black 的信息,而Q2不仅接受black 的信息,还接受green 的信息。

测试代码是按照链接地址上的地方进行测试的,此处就不粘贴了(下同)

|Topic模式:

先复习一下topic模式

TopicExchange 转发消息主要是根据通配符,队列和交换机的绑定会定义一种路由模式。这样就要求 路由键必须是一串字符用(.) 隔开如 :agreements.us 路由模式必须包含一个 匹配符(*表示一个词 #表示零个或多个词)如:agreements..b.*、agreements.eu.berlin.#

topic和 direct 类似, 只是匹配上支持了"模式", 在"点分"的 routing_key 形式中

 

交换器使得来自不同的源头的消息可以到达一个对列,可以理解为模糊匹配

Tip:交换器说到底是一个名称与队列绑定的列表。当消息发布到交换器时,实际上是由你所连接的信道,将消息路由键同交换器上绑定的列表进行比较,最后路由消息

 

|Fanout模式

FanoutExchange 消息广播的模式,不管路由键或者是路由模式,会把消息发给绑定给它的全部队列,如果配置了routing_key会被忽略。

 

四、RabbitMQ高级

       这部分的内容其实在第二部分和第三部门都有过一些实现和介绍,此处就不详述。

1、RabbitMQ的消息分发机制

http://blog.csdn.net/xiaoxian8023/article/details/48681987

|Round-robin(轮询分发)

使用任务队列的优点之一就是可以轻易的并行工作。如果我们积压了好多工作,我们可以通过增加工作者(消费者)来解决这一问题,使得系统的伸缩性更加容易。在默认情况下,RabbitMQ将逐个发送消息到在序列中的下一个消费者(而不考虑每个任务的时长等等,且是提前一次性分配,并非一个一个分配)。平均每个消费者获得相同数量的消息。这种方式分发消息机制称为Round-Robin(轮询)。

 

|Fair dispatch(公平分发)

任务分发仍然没有完全按照我们想要的那样。比如:现在有2个消费者,所有的奇数的消息都是繁忙的,而偶数则是轻松的。按照轮询的方式,奇数的任务交给了第一个消费者,所以一直在忙个不停。偶数的任务交给另一个消费者,则立即完成任务,然后闲得不行。而RabbitMQ则是不了解这些的。

      这是因为当消息进入队列,RabbitMQ就会分派消息。它不看消费者为应答的数目,只是盲目的将第n条消息发给第n个消费者。为了解决这个问题,我们使用basicQos( prefetchCount = 1)方法,来限制RabbitMQ只发不超过1条的消息给同一个消费者。当消息处理完毕后,有了反馈,才会进行第二次发送。

 Tip:如果所有的工作者都处于繁忙状态,你的队列有可能被填充满。你可能会观察队列的使用情况,然后增加工作者,或者使用别的什么策略。 还有一点需要注意,使用公平分发,必须关闭自动应答,改为手动应答

 

2、消息应答与消息持久化

http://blog.csdn.net/xiaoxian8023/article/details/48710653

 

| Message acknowledgment(消息应答)

执行一个任务可能需要花费几秒钟,你可能会担心如果一个消费者在执行任务过程中挂掉了。基于现在的代码,一旦RabbitMQ将消息分发给了消费者,就会从内存中删除。在这种情况下,如果杀死正在执行任务的消费者,会丢失正在处理的消息,也会丢失已经分发给这个消费者但尚未处理的消息。

      但是,我们不想丢失任何任务,如果有一个消费者挂掉了,那么我们应该将分发给它的任务交付给另一个消费者去处理。

      为了确保消息不会丢失,RabbitMQ支持消息应答。消费者发送一个消息应答,告诉RabbitMQ这个消息已经接收并且处理完毕了。RabbitMQ可以删除它了。

      如果一个消费者挂掉却没有发送应答,RabbitMQ会理解为这个消息没有处理完全,然后交给另一个消费者去重新处理。这样,你就可以确认即使消费者偶尔挂掉也不会不丢失任何消息了。

      没有任何消息超时限制;只有当消费者挂掉时,RabbitMQ才会重新投递。即使处理一条消息会花费很长的时间。

      消息应答是默认打开的。我们明确地把它们关掉了(autoAck=true)。现在将应答打开,一旦我们完成任务,消费者会自动发送消息应答。

 

| Message durability(消息持久化)

如果RabbitMQ服务器停止,我们的任务仍将失去!当RabbitMQ退出或者崩溃,将会丢失队列和消息。除非你不要队列和消息。两件事儿必须保证消息不被丢失:我们必须把“队列”和“消息”设为持久化。

尽管这行代码是正确的,但他不会在我们当前的设置中起作用。因为我们已经定义了一个名叫hello的未持久化的队列。RabbitMQ不允许使用不同的参数设定重新定义已经存在的队列,并且会向尝试如此做的程序返回一个错误。一个快速的解决方案——就是声明一个不同名字的队列,比如task_queue。

      (当然,我们也可以登录到RabbitMQ的服务管理页面,RabbitMQ默认的端口是5672,管理页面默认端口是15672,页面地址为:http://localhost:15672,使用是用户名和密码登录。RabbitMQ的默认密码和用户名都是guest。点开“queue”那栏,可以看到队列列表,点击“hello”杜列,会展开队列的详细信息。把页面拉到最后,有一项“Delete / purge”,点开,点击“Delete”按钮,就可以把队列删除掉了。然后再运行代码的时候,就会创建一个支持持久化的hello队列。)

      上述的代码需要在生产者和消费者都要作出同样的修改。

      在这一点上我们确信task_queue的队列不会丢失,即使RabbitMQ服务重启。现在我们需要将消息标记为持久性的——通过设置MessageProperties(实现BasicProperties)为PERSISTENT_TEXT_PLAIN。

      现在你可以启动RabbitMQ服务器,执行一次生产者NewTask的程序,然后关闭服务器,再重新启动服务器,运行消费者Work做下实验。可以发现消费者依旧可以读出消息来。说明在RabbitMQ服务器关闭后,消息和队列信息都已经做了持久化。再次启动后,会重新加载到服务器中,消费者运行后,就可以正常的从队列中获取消息了。

 

3、发布/订阅(略)

http://blog.csdn.net/xiaoxian8023/article/details/48729479

将消息发送给多个消费者。这种模式叫做“发布/订阅”

 

4、路由选择

http://blog.csdn.net/xiaoxian8023/article/details/48733249

| Bindings(绑定)

绑定表示转换器与队列之间的关系。可以简单的认为:队列对该转发器上的消息感兴趣。 绑定可以设定额外的routingKey参数。为了与避免basicPublish方法(发布消息的方法)的参数混淆,我们准备把它称作绑定键(bindingkey)

channel.queueBind(queueName, EXCHANGE_NAME, "black"); 

| Direct exchange(直接转发)

消息会被推送至绑定键(binding key)和消息发布附带的选择键(routing key)完全匹配的队列

| Multiple bindings(多重绑定)

使用一个绑定键绑定多个队列是完全合法的

 

| Topic exchange(主题转发器)

发送给主题转发器的消息不能是任意设置的选择键,必须是用小数点隔开的一系列的标识符。这些标识符可以是随意,但是通常跟消息的某些特性相关联

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值