声明

本文欢迎转载,系博主原创,本文原始链接地址:http://www.cnblogs.com/DjlNet/p/7654902.html


前言

此文章,是承接上篇:【框架学习与探究之消息队列--EasyNetQ(1)】未完待续篇,依然对消息队列及其应用的一个补充说明和一些博主的见解。这里说一点废话:就博主自身所见而言的话还有后面了解,现在招聘说明当中部分虽然没有明确提出关于消息队列方面的需求,但是面试官看见几年工作经验的你肯定会多多少少问问关于对此的认识和见解,所以当你以一种颇为了解与实战的姿态说出自己的看法的时候,相信肯定会对这场面试的你加分不少的呐,从而也说明了现今开发当中消息队列的重要性,说到底,它RabbitMQ/EasyNetQ如果能给你带来加分的筹码以及薪资的提升,学习它何乐而不为呐!!!或许这就是面向工资编程吧!!


继续EasyNetQ文档划重点与测试

这里再次强调在基于系统之间的消息交互开发方面,尤其需要注意的就是消息的Publish/Consumer的两种操作的强制落地的思考与解决方案,博主在上文做出一定的见解和实际操作方案。

4、关于交换机的Type以及命名、消息队列的命名

这里如果使用了EasyNetQ框架的情况下(如其名字一样为了简单使用使用了约束),框架会产生如下约束:1、发布订阅的消息必须是.NET Class类型,且类似与DTO一样Public访问修饰符和默认的构造函数没有方法 2、根据消息的类型来进行路由选择。这里首先要说明的是,交换机的名字默认情况就是:因为上面的约定,所以例如当我们的消息定义为public class TextMessage{}的时候,那么默认情况所产生交换机的名字就是:Messages.TextMessage:Messages类型的全名称:程序集的名字并且Exchange类型指定为了Topic,这里需要说明一下就是在几种交换机类型当中,Topic是最灵活可以变相的通过它实现其他类型的工作方式,所以我们的EasyNetQ直接指定该工作类型为了简单化的使用原则;接下来在消费者去订阅该消息的时候默认情况产生队列的名字就是:Messages.TextMessage:Messages_{YourSubscriptionId} 这里YourSubscriptionId可以为empty那么产生的队列名字就会与交换机同名了。

那么框架这里提供这个YourSubscriptionId玩意儿给使用者是干吗使用的呐?

这里博主的理解就是有这个功能点的实现,多半是有这方面的需求,例如当我们需要一个交换机绑定多个队列,但是使用的消息格式是同一个.NET类型,这里就可使用自定义的SubscriptionId来实现多队列多消费者模式,例如日志分发消息系统的需求,也可以当这个标记符来当做类似与模块或者系统的标记达到一看见队列的名字就知道消费者的创建者,等等一些具有意义的标记,切记注意最大字符个数225,还有一点就是如何实现工作队列模式?这里只需要重复订阅同一个消息类型且SubscriptionId一致即可实现多个消费者对同一个队列的共同消费模式,例如当出现既有的消费者已经满足不了处理效率支持的情况下,但是又不想改动原先系统的情况,就可以实现无痛式的增加一个消费者来共同消费达到负载均衡的效果,以及诸如此类的场景。注意:当订阅者消息类型一致的时候,SubscriptionId不同的话就会形成消息复制分发的效果

当然拉,如果想实现更改默认的框架约束自定义交换机和队列名字,参考如下(博主实验证明可行):

[Queue("TestMessagesQueue", ExchangeName = "MyTestExchange")]
public class TestMessage
{
public string Text { get; set; }
}

但是这里一般情况博主认为,就如同代码就是最好的注释一样,让消息类型作为消息队列的名字也是一种不错的解决方案,有一种自圆其说的感觉,从而也印证了框架作者如出一辙的想法就是采用消息类型路由的做法


5、主题路由与消息过滤

这里主要就是交换机的类型了Topic使用了,这里具体的解释与使用参考第一篇文中给出的地址,这里博主需要说明的是框架中注意点当多个消费者指定了相同的消息类型且指定相同的SubscriptionId,那么这些消费者就算是指定了自己的WithTopic也不会达到消息过滤的效果,因为Topic的RouteKey是作用于交换机与队列的不是消息本身,那么既然消费者们都已经是消费同一个队列了那肯定就不会产生消息的过滤了

那么在此框架中提供topic有什么其他用途么,我该怎么使用呐

这里我们依然采用举例子(当然可能例子有些牵强为了迎合我们的topic功能点)的方式来说明,假设我们现在有性能监控系统(A)、日志处理报警系统(B),这里我们其他应用系统底订单系统、库存系统、财务系统等产生的性能安全错误相关消息日志都会统统就发送到A,然后由A分析和挑选出需要转发到B的消息以LogInfoMessage的方式统一推送到MQServer当中,这里使用了同一个消息类型就意味着同一个交换机,这里Publish的时候根据不同携带了不同的RouteKey,例如订单系统->Order.Create、Order.Cancel等等,库存系统->Inventory.Adjust、Inventory.Delivery等等,诸如此类的路由键,然后假设我们的B系统有LogInfoMessage的消费者们,它们可能并不需要关心所有的日志消息,例如OrderLogInfoMessageConsumer只关心订单相关的,配置为 WithTopic("Order.#"),类似InventoryLogInfoMessageConsumer只关心库存相关的日志,配置为了 WithTopic("Inventory.#"),且消费者需要指定唯一的标识,这样一来将会形成一个交换机绑定了多个多个队列以及各自的消费者们,具体参考如下:



上图是关于RabbitMQ交换机的bindings配置图也说说明了问题,这样一来就可以实现同一个消息类型也可以实现消息的按需求过滤式消费了,参考配置对应代码:

例子发布者代码如图
:



例子消费者代码如下

bus.Subscribe<LogInfoMessage>(string.Empty, x => Console.WriteLine(x.Body + " " + x.Creator));
bus.Subscribe<LogInfoMessage>("Order", x => Console.WriteLine(x.Body + " " + x.Creator), x => x.WithTopic("Order.#"));
bus.Subscribe<LogInfoMessage>("Inventory", x => Console.WriteLine(x.Body + " " + x.Creator), x => x.WithTopic("Inventory.#"));
bus.Subscribe<LogInfoMessage>("Finance", x => Console.WriteLine(x.Body + " " + x.Creator),x => x.WithTopic("Finance.#"));
bus.Subscribe<LogInfoMessage>("Order_Inventory", x => Console.WriteLine(x.Body + " " + x.Creator),x => x.WithTopic("Order.#").WithTopic("Inventory.#"));

以上例子便展示topic的应用场景和使用规则,这与上面讲到的SubscriptionId有一定关系,它产生了不同的队列才得以实现不同的队列用不同的routekey来绑定交换机才足以实现消息可以根据自定规则投递到对应的队列当中去


6、自动订阅者划重点

这里EasyNetQ,可以使用它来轻松扫描实现IConsume 或IConsumeAsync 的接口的类的特定程序集,然后自动将这些消费者订阅到RabbitMQ中去。 IConsume 的实现将使用总线Subscribe方法,而IConsumeAsync 的实现将使用总线SubscribeAsync方法。

1、一个消费者可以实现多个泛型消费接口或者异步的泛型消费接口,就可以实现承担消费多种类型的消息的功能

2、[ForTopic("Topic.Foo")]使用该标签在 实现类的方法上面就可以实现与普通订阅使用withtopic同样的效果

3、[AutoSubscriberConsumer(SubscriptionId = "MyExplicitId")] 为消费者对应的队列名称后缀

4、通过控制 AutoSubscriber 的构造函数的 GenerateSubscriptionId 就可以实现全局自动订阅者的配置项 、ConfigureSubscriptionConfiguration 实现全局消费者的配置

5、[SubscriptionConfiguration(CancelOnHaFailover = true, PrefetchCount = 10)] 控制消费者配置,作用于实现类的方法上面

6、替换 AutoSubscriber 的 MessageDispatcher 可以实现我们自定义消费者生产逻辑


总结

**通过第二篇文章我们再一次了解了如何通过框架去了解RabbitMq,以及使用和注意事项,当然这个离我们正真使用到项目集成到系统当中去还有一定的距离,不过相信阅读了这两篇文章的园友,应该还是有所收获,这里博主不光光是只是对框架做了一定的分许和解读,主要还是对rabbitmq本身一些注意点和特性机制做了一定实验研究,也从消息落地方面做了一定设想,这样在改善现有系统和以后新系统的搭建的时候能够做到心中有数的话也是起到了一定的作用了。这里抛出两个问题,也是博主后续将会去了解,1、就目前而言项目中发生了,消息的无故重发,因为隔离了系统的耦合性,导致消息内容一致却被重复处理的问题?提示:做到消息内容处理的幂等验证,不能依赖发送方的可靠性 2、关于如何搭建集群的rabbitmq服务与使用easynetq访问?集群搭建上文有参考链接,这里给出easynetq关于cluster support参考链接:https://github.com/EasyNetQ/EasyNetQ/wiki/Cluster-Support **

如果上述内容对您来说有一定作用的话,您的点赞和评论都是对博主最大的支持的呐,O(∩_∩)O嗯!

【框架学习与探究之消息队列--EasyNetQ(2)】的更多相关文章

  1. 【框架学习与探究之消息队列--EasyNetQ(1)】

    前言 本文欢迎转载,实属原创,本文原始链接地址:http://www.cnblogs.com/DjlNet/p/7603554.html 废话 既然都是废话了,所以大家就可以跳过了,这里是博主有事没事 ...

  2. 深入剖析 RabbitMQ —— Spring 框架下实现 AMQP 高级消息队列协议

    前言 消息队列在现今数据量超大,并发量超高的系统中是十分常用的.本文将会对现时最常用到的几款消息队列框架 ActiveMQ.RabbitMQ.Kafka 进行分析对比.详细介绍 RabbitMQ 在 ...

  3. enode框架step by step之消息队列的设计思路

    enode框架step by step之消息队列的设计思路 enode框架系列step by step文章系列索引: enode框架step by step之开篇 enode框架step by ste ...

  4. 【框架学习与探究之宿主服务--Topshelf】

    前言 此文欢迎转载,原始链接地址:http://www.cnblogs.com/DjlNet/p/7603819.html 正文 原先也偶然见过这个关键词,当时只是有个大致了解貌似和WinServic ...

  5. 【框架学习与探究之定时器--Hangfire】

    声明 本文欢迎转载,请注明文章原始出处:http://www.cnblogs.com/DjlNet/p/7603632.html 前言 在上篇文章当中我们知道关于Quartz.NET的一些情况,其实博 ...

  6. 【框架学习与探究之日志组件--Log4Net与NLog】

    前言 本文欢迎转载,作者原创地址:http://www.cnblogs.com/DjlNet/p/7604340.html 序 近日,天气渐冷,懒惰的脑虫又开始作祟了,导致近日内功修炼迟迟未能进步,依 ...

  7. Redis学习之实现优先级消息队列

    很久没有写博客了,最近简单的学习了一下Redis,其中学习了一下用Redis实现优先级消息队列.关于更多更为详细的可以在www.redis.cn找到相关资料. 对于熟悉Redis的童鞋提到队列很自然的 ...

  8. C# .net 使用rabbitmq消息队列——EasyNetQ插件介绍

    EasyNetQ 是一个简洁而适用的RabbitMQ .NET类库,本质上是一个在RabbitMQ.Client之上提供服务的组件集合.

  9. 【框架学习与探究之定时器--Quartz.Net 】

    声明 本文欢迎转载,原文地址:http://www.cnblogs.com/DjlNet/p/7572174.html 前言 这里相信大部分玩家之前现在都应该有过使用定时器的时候或者需求,例如什么定时 ...

随机推荐

  1. kickstart部署及使用

    Linux运维:kickstart : 矮哥linux运维群:93324526 1.环境检查 [root@m01 ~]# cat /etc/redhat-release CentOS release ...

  2. 团队作业8——第二次项目冲刺(Beta阶段)--5.21 second day

    团队作业8--第二次项目冲刺(Beta阶段)--5.21 second day Day two: 会议照片 项目进展 今天是beta冲刺的第二天,组长还在准备考试当中,我们继续做前端改进和后端安排,今 ...

  3. 201521123035《Java程序设计》第五周学习总结

    1. 本章学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 1.2 可选:使用常规方法总结其他上课内容. 接口是一种特殊的抽象类,是对行为的抽象,它不能使用new进行实例化,接口中可以包 ...

  4. 201521123048 《Java程序设计》第4周学习总结

    1. 本周学习总结 1.1 尝试使用思维导图总结有关继承的知识点. 1.2 使用常规方法总结其他上课内容. 1.多态:使用单一接口操作多种类型的对象. 2.private修饰属性,public修饰方法 ...

  5. 201521123117 《Java程序设计》第10周学习总结

    1. 本周学习总结 2.2. 书面作业 1.finally 题目4-2 1.1 截图你的提交结果(出现学号) 1.2 4-2中finally中捕获异常需要注意什么? 只要try执行了之后,finall ...

  6. 多线程:多线程设计模式(二):Future模式

    一.什么是Future模型: 该模型是将异步请求和代理模式联合的模型产物.类似商品订单模型.见下图: 客户端发送一个长时间的请求,服务端不需等待该数据处理完成便立即返回一个伪造的代理数据(相当于商品订 ...

  7. 深度学习(一)cross-entropy softmax overfitting regularization dropout

    一.Cross-entropy 我们理想情况是让神经网络学习更快 假设单模型: 只有一个输入,一个神经元,一个输出   简单模型: 输入为1时, 输出为0 神经网络的学习行为和人脑差的很多, 开始学习 ...

  8. mount挂载和交换分区swap

    目录 mount挂载 挂载方法 选项 查看设备 卸载命令 文件挂载配置文件fstab 交换文件与分区 swap优先级 三个工具free,df,du 扩展 移动介质 使用光盘 挂载USB设备 mount ...

  9. POJ--3258 River Hopscotch (最小值最大化C++)

    River Hopscotch Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 15273   Accepted: 6465 ...

  10. 1-SDK开发初探-8266

    先分享一个比较感动的事情 其实做实物是因为好多人看了我的文章之后还是会遇到各种各样的问题,然后呢真是让亲们搞的自己好累.......所以就想着如果亲们用自己做的板子,出现什么问题能够快速的解决,,而且 ...