RabbitMQ 更好的设计方法是什么?
What is better design approach for RabbitMQ?
过去几周我一直在研究 RabbitMQ
并开发了以下设计模式
producer <--> Exchange <---> queues <---> consumer.
我用过几个 RabbitMQ 客户端,比如 EasyNetQ
和 MassTransit
。两个客户端都使用我的上述设计,但是它们之间的一个共同点是,如果 Exchange
不存在,它会创建一个,类似地,如果队列不存在,它会相应地创建一个。
但是,我认为从生产者或消费者创建交换、队列和绑定是一种好的设计方法吗?
在RabbitMQ Management里面手动创建exchange和queues是不是更有意义?然后阻止Producer和Consumer在代码中创建上面的内容?
但我更关心的是,如果交换器和队列被删除,那么它也会破坏生产者和消费者吗?
大家有什么建议吗?
您的生产者和消费者的 CD(持续部署)应该负责创建这些资源,您的 CD 应该检查资源是否存在,如果不存在则创建。
您应该避免 creating/deleting 来自代码的资源,生产者和消费者实际上应该 publish/consume,如果您使用的是云提供商,则根本不应授权代码操作资源。
我的做法:
- consumer/producer 使用的 Exchanges/Queues 的信息应该从设置文件中读取。
- 部署开始时,CD 应该会创建所需的 exchanges/queues。
- CD 然后应该通过环境变量覆盖设置。
- Producer/Consumer 将处理 CD 提供的资源信息,这样 CD 可以确保双方使用相同的 queue/exchange 信息。
此外,您还将减少沟通不畅、资源过度使用和资源操纵(如删除队列!)的风险。
在生产中,Nothing/No除了少数真正知道自己在做什么的人之外,应该授权一个人编辑资源。
我认为这个问题有两个部分。我会试着分别拿走每一个:
拓扑结构
在您的图表中,您的生产者将消息放入消费者的队列中。它根本不适用于 RabbitMQ:
The core idea in the messaging model in RabbitMQ is that the producer never sends any messages directly to a queue.
(from the docs)
因此,正如您所注意到的,您提到的消息传递中间件库总是创建一个队列和一个与该队列匹配的交换器,然后将它们绑定在一起。通过这样做,它们使您能够 "publish" 将消息发送到绑定到您的消费者队列的特定交换,因此您可以获得 发送 功能。
所以,在幕后,它仍然是发布-订阅。
使用图书馆或自己做事
设置队列和交换是一项繁琐的工作。在某些情况下,您肯定希望在低级别进行控制并从代码中处理所有这些事情。
但是,使用消息中间件,无论是 EasyNetQ、MassTransit 还是 NServiceBus 都非常有价值。所有这些库都具有全面的拓扑管理功能,使开发人员能够专注于交付价值,而不是处理交换和队列。
在许多情况下,使用基于类型的路由(就像每个库所做的那样)非常有意义。
这里我给你一个快速列表,列出你需要在代码中做的事情,或者如果你选择不使用消息传递中间件库,则手动做:
- 正在配置拓扑
- 配置路由
- 使用重试和重新传递处理异常
- 控制消息消费者的作用域依赖关系
- 记录和追踪
- 计划
- Long-运行 进程和分布式事务
该列表目前还不够全面,但它给了您思路。如果您准备好自己解决所有这些问题,那就去做吧。
过去几周我一直在研究 RabbitMQ
并开发了以下设计模式
producer <--> Exchange <---> queues <---> consumer.
我用过几个 RabbitMQ 客户端,比如 EasyNetQ
和 MassTransit
。两个客户端都使用我的上述设计,但是它们之间的一个共同点是,如果 Exchange
不存在,它会创建一个,类似地,如果队列不存在,它会相应地创建一个。
但是,我认为从生产者或消费者创建交换、队列和绑定是一种好的设计方法吗?
在RabbitMQ Management里面手动创建exchange和queues是不是更有意义?然后阻止Producer和Consumer在代码中创建上面的内容?
但我更关心的是,如果交换器和队列被删除,那么它也会破坏生产者和消费者吗?
大家有什么建议吗?
您的生产者和消费者的 CD(持续部署)应该负责创建这些资源,您的 CD 应该检查资源是否存在,如果不存在则创建。
您应该避免 creating/deleting 来自代码的资源,生产者和消费者实际上应该 publish/consume,如果您使用的是云提供商,则根本不应授权代码操作资源。
我的做法:
- consumer/producer 使用的 Exchanges/Queues 的信息应该从设置文件中读取。
- 部署开始时,CD 应该会创建所需的 exchanges/queues。
- CD 然后应该通过环境变量覆盖设置。
- Producer/Consumer 将处理 CD 提供的资源信息,这样 CD 可以确保双方使用相同的 queue/exchange 信息。
此外,您还将减少沟通不畅、资源过度使用和资源操纵(如删除队列!)的风险。
在生产中,Nothing/No除了少数真正知道自己在做什么的人之外,应该授权一个人编辑资源。
我认为这个问题有两个部分。我会试着分别拿走每一个:
拓扑结构
在您的图表中,您的生产者将消息放入消费者的队列中。它根本不适用于 RabbitMQ:
The core idea in the messaging model in RabbitMQ is that the producer never sends any messages directly to a queue. (from the docs)
因此,正如您所注意到的,您提到的消息传递中间件库总是创建一个队列和一个与该队列匹配的交换器,然后将它们绑定在一起。通过这样做,它们使您能够 "publish" 将消息发送到绑定到您的消费者队列的特定交换,因此您可以获得 发送 功能。
所以,在幕后,它仍然是发布-订阅。
使用图书馆或自己做事
设置队列和交换是一项繁琐的工作。在某些情况下,您肯定希望在低级别进行控制并从代码中处理所有这些事情。
但是,使用消息中间件,无论是 EasyNetQ、MassTransit 还是 NServiceBus 都非常有价值。所有这些库都具有全面的拓扑管理功能,使开发人员能够专注于交付价值,而不是处理交换和队列。
在许多情况下,使用基于类型的路由(就像每个库所做的那样)非常有意义。
这里我给你一个快速列表,列出你需要在代码中做的事情,或者如果你选择不使用消息传递中间件库,则手动做:
- 正在配置拓扑
- 配置路由
- 使用重试和重新传递处理异常
- 控制消息消费者的作用域依赖关系
- 记录和追踪
- 计划
- Long-运行 进程和分布式事务
该列表目前还不够全面,但它给了您思路。如果您准备好自己解决所有这些问题,那就去做吧。