【EasyNetQ笔记】介绍

介绍

EasyNetQ是一个在RabbitMQ.Client类库之上提供服务的组件集合。做了这些事情,像序列化、错误处理、线程管理、连接管理等。通过一个Mini-Ioc容器组织在一起。你能很容易用你自己实现去替换这些组件。所以如果你喜欢用XML序列化而不是用JSON,仅仅需要以一个ISerializer的实现,然后注册到这个容器中。
这些组件由IAdvancedBus API提供。你能够通过这个API运行很多AMQP方法。这个API对你隐藏了唯一AMQP概念是channels。这是因为channels是一个复杂的底层概念。
IBus API包括一系列消息模式:Publish/Subscribe, Request/Response,和 Send/Receive. 这是EasyNetQ坚持的设计思想,即尽可能简单的使用RabbitMQ。
这些模式的后面是这个 IBus API. 80%的用户的工作,在80%的时间都会使用IBus。它不是完备的API,如果你想实现的功能这个IBus没有提供,那么你应该使用IAdvancedBus。

为什么需要EasyNetQ

RabbitMQ不是已经有了 .NET client?那么为什么我需要EasyNetQ呢?
RabbitMQ .NET client 实现了AMQP协议的客户端(RabbitMQ实现了服务器端)。 AMQP是为HTTP协议设计的。它的设计是跨平台的和与语言无关的。它也旨在灵活支持多种基于交换/绑定/队列模型的消息传递模式。
RabiitMQ Client 非常地灵活,但是伴随着灵活性而来是复杂性。这意味着你为了需要写大量代码,以便执行RabbitMQ client。
通常,这些代码包括一下这些:

  • 实现消费者重新连接。假如连接崩溃了或者RabbitMQ 服务挂了,EasyNetQ将恢复轮询终结点直到重新连接成功
  • 实现消息传递模式,例如Publish/SubscribeRequest/Response。尽管.NET client也提供了一些这样的支持。
  • 实现路由策略。你将需要设计你如何去exchange-queue绑定。并且你将设计怎样在生产者和消费者之间进行消息路由。
  • 实现消息的序列化/反序列化。 你将如何转换AMQP的二进制消息为你编程语言能理解的格式?
  • 为订阅去实现一个消费者线程。你将需要有一个专门的消费者循环等待你订阅的消息。你会如何处理多个订阅者
  • 懂得和实施服务质量设置。你需要什么样的设置来确保一个可靠的客户端。
  • 实现一个错误处理策略。假如接受到一个错误的消息,或者发生一个未处理异常被抛出,你的客户端应该做什么呢?
  • 实现发布者可靠的消息确认。
    EasyNetQ目标是在AMQP之上封装所有这些关注点在一个简单好用的类库中。EasyNetQ有在高容量商业环境中数年使用RabbitMQ的经验。

重新连接

数据库通讯是打开一个连接,执行sql,关闭连接。RabbitMQ与数据库连接不同,因为连接倾向于在应用的整个生命周期内保持连接状态。通常你打开一个连接,创建一个订阅,然后打开连接后,等待消息到来。EasyNetQ不能保证代理在所有的时间都是可用的。相反它使用了延迟连接的方法,在后台线程轮询终结点,直到连接成功。假如服务器出于任何原因连接断开了(可能是网络故障,或许是RabbitMQ Server自身的原因断开了),EasyNetQ将恢复轮询终结点直到重新连接成功。
EasyNetQ实现了一个延迟连接策略。这个策略假设这个代理不会总是可用的。当你第一次通过使用RabbitHutch.CreateBus连接到这个代理时,EasyNetQ开启一个连接,不断循环尝试去连接代理,如果你指定的连接字符串地址的代理没有处于可用状态,你会从消息信息日志中看到'Trying to Connect'。订阅者能够使用bus.Subscribe方法去订阅,即使当这个代理不可用时。这个订阅的细节会被EasyNetQ缓存。 当代理恢复可用时,这个正在不断循环尝试连接将会成功连接到代理,并且所有缓存的订阅一同恢复。
同样,当EasyNetQ和代理连接中断时,它将返回到循环连接,你在日志中看'Trying to Connect'信息。一旦连接重新建立,被缓存的订阅者将再次被建立。最后结论就是,在正在运行环境中,无论在网络断开时,或是你需要在被你的RabbitMQ代理拒绝时,你能够保留你的订阅者。

错误处理策略

EasyNetQ为订阅功能实现了一个基于内存的内部使用的队列。消息通过网络从RabbitMQ中接收到后,会把消息放到这个内存队列中。一个订阅者线程从这个内存队列拿走消息后,回调自己提供的消息处理代码。一旦这个回调完成后,EasyNetQ会发送'Ack'给RabbitMQ。没有收到'Ack'前,这个消息不会从RabbitMQ消息队列中被删除。如果你的服务在处理这个消息时挂掉了,这个消息以及EasyNetQ内存队列中的所有消息都将呆在RabbitMQ队列中。直到你的服务再次连接上后,这些消息将会再次被发送。

当消费一个消息时,订阅回调抛出异常:
如果你的订阅回调抛出异常,EasyNetQ将会拿到这个正在被消费的消息,包装这个消息到一个指定错误消息中。这个错误消息将会被发布到EasyNetQ的错误队列(名字是EasyNetQ_Default_Error_Queue)。你应该监控这个错误队列中的消息。这个错误消息包括所有必要的信息,例如需要重新发布的原始消息,以及异常的类型,异常信息和堆栈信息。你可能使用EasyNetQ.Hosepipe工具重新发布错误信息。

参考:
https://github.com/EasyNetQ/EasyNetQ/wiki/Quick-Start
https://www.cnblogs.com/forcesoul/category/1125580.html

posted @ 2020-09-05 08:04  .Neterr  阅读(713)  评论(0编辑  收藏  举报