RabbitMQ: AMQP Channel 最佳实践 已翻译 100%

oschina 投递于 2013/09/25 08:06 (共 4 段, 翻译完成于 09-26)
阅读 11806
收藏 7
0
加载中

关于AMQP通道处理的最佳实践问题我已经迷惑了很久了。本文中,我尝试阐述了我现在的想法,同时也期待获得读者的反馈。

消息代理服务器和客户端之间的会话是双向的。客户端和服务器都可以创建‘通信事件’;客户端可以调用服务器上的方法: 比如说‘publish’ 或‘declare’;而服务器也可以调用客户端上的方法,比如‘deliver’或者‘reject’。由于客户端需要从服务器获取方法,所以它需要在其生存期内一直保持连接的开放状态。这意味着连接可能会持续较长时间;几小时,几天或者几周。不管对客户端还是服务器来说,保持这些连接是很耗费资源的。为了在不使用大量的物理TCP/IP连接的情况下就能拥有大量的逻辑连接,AMQP使用了‘通道(channel)’ 的概念(在其Java and .NET客户端的IModel接口中有较为模糊的描述)。你可以在单个连接中创建多个channel,相对来说创建和销毁它们的代价要小的多。

lwei
翻译于 2013/09/25 09:37
1

那么关于如何处理这些通道,有什么推荐规则吗?我每次操作都应该创建一个新的通道吗?或者,我应该只维持一个通道并且每一个方法都通过它来执行?

首先是一些硬性规则(注意这里我参考的是RabbitMQ的.NET客户端,其它客户端可能会有不同的行为):

通道不是线程安全的。 你应该在每个线程中都创建一个通道。下面这段话来自.NET客户端的文档(2.10章节):

“通常来说,IModel实例不应当被多个线程并发使用: 关于IModel 实例的线程所有权,应用程序代码应当有清晰的概念。”

很明显在Java客户端中这不是一个硬性规则,只是一个好建议。java客户端把所有调用都串行化安排给一个通道。

lwei
翻译于 2013/09/25 10:16
1

当同一个通道收到数据后必须发出确认信息 发送标记的作用域是通道,如果一个确认信息从它收到信息的通道发送到另一个通道的话就会引发通道错误。当你在不同线程里调用basic.consumer发送确认信息时,与上面提到的“通道不是线程安全的”有些矛盾,但这看起来是可以接受的。

软件开发者的一些建议:

对于每一个用户都创建通道。我总是把用户和通道作为整体考虑:当我创建一个用户,于此同时我也会创建一个通道与之对应。当用户消失,通道和vice-versa也亦然。
yale8848
翻译于 2013/09/26 18:49
1

不要把发布和消费混为一谈。如果你能按照上面的建议做,这就意味着你将创建很多通道服务于每一个用户。这将让你为服务端和客户端创建独立的通道。

维护一个长时间发布通道。最近我实现了EasyNetQ,它可以为用户发布信息而创建通道。现在我认为这是个错误。这里的模式是:创建通道,发布,销毁通道。这个模式在当发布者要确认  需要保持通道打开直到你收到ACK或NACK时工作的不好。尽管创建个通道是很轻的,但仍然需要消耗的。现在我致力于在一个工作线程中和在一组发布(并宣布)中维护一个单发布通道。这有潜在的瓶颈,但是令人映象深刻的是其非事务性的发布意味着我不是过分的关注它。

yale8848
翻译于 2013/09/26 19:46
1
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(1)

qwfys
qwfys
^_^
返回顶部
顶部