你真的需要消息队列吗

我是一个极简主义者,我不喜欢让软件过早或不必要地复杂化。向软件系统添加组件是增加复杂性的一种方法。让我们以消息团队为例。

消息队列是一个系统,使您能够获得容错、分布式、解耦的架构功能。在纸上,它看起来不错。

在您的应用程序中,可能有许多场景正在排队。您可以查看这篇文章,了解消息队列的优点,以了解适当的场景是什么。但不要仅仅因为它太好而不能解耦。让我们看一个示例——您希望将邮件发送出去,命令处理将被解耦。

因此,您将消息发送到消息队列,然后邮件处理系统取出消息并发送消息。如何在独立的单一类路径中实现此功能?使您的订单处理服务依赖于一个邮件服务,然后调用sendEmail()方法而不是sendToMQ()方法。如果使用消息队列,则需要定义两个系统都能识别的消息格式;如果不使用消息队列,则必须定义一个方法签名。有什么本质的区别吗?不是真的。

但你可能会有其他想要特别关注某一信息的消费者?这是有可能的,不仅仅是我们在这里谈论的项目。尽管这是可能的,但与添加另一个方法调用相比,它可能不值得。耦合吗?是的。但是这种耦合没有什么不方便的。

那么如何处理峰值流呢?您可以通过消息队列将请求放置到持久队列中,然后将它们一起处理。这是一个非常有用的特性,但它也仅限于几个因素——您的请求是在UI背景中处理的,还是需要立即响应?Serlvet容器线程池,在某种程度上可以作为队列,用户最终会得到响应,但需要等待(如果超时时间的线程太短,请求可能会丢失)。

您可以使用一个内存队列来存储较重的请求(在UI背景中处理)。注意,默认情况下,队列不是高可用性的。例如,如果消息队列节点被挂起,您的消息将丢失。因此,与其在应用程序节点中使用内存队列,还可以使用消息队列,这可能没有任何优势。

消息队列使我们能够进行异步处理——这是一个有用的特性。当用户在等待的时候,你不想做一些繁重的事情。但是您也可以使用一个内存队列或者仅仅启动一个新线程。所以还有一个问题,如果信息丢失了,会有问题吗?如果应用程序处理请求的节点,可以恢复它吗?您会发现这种情况经常发生,如果您没有处理所有的消息,那么很难确保功能是正确的。因此,只需要异步地处理沉重的调用。

将消息放到队列中另一个组件处理,对于这个场景,如果消息丢失是不可接受的,那么还有一个简单的解决方案——数据库。您可以将处理的数据存储到数据库中。然后运行调度作业,选择所有未处理的记录并异步处理它们。处理完成后,将标志设置为true。我经常使用这种方法,包括在一些大型在线系统中,它也很好用。

您还可以持续地扩展应用程序节点,只要它们在内存中没有持久的状态。无论您是否使用消息队列(临时内存处理队列都不是持久的)。

为什么我应该提供替代频繁使用的消息队列?因为如果出于不适当的原因选择它,消息队列就会成为一个负担。他们不像他们那样容易使用。首先,它有一个学习曲线。一般来说,集成的组件越多,就越容易出现问题。其次,设置和配置它的成本。例如,当消息队列需要在集群中运行时,例如多个数据中心,这就变得复杂了。

高可用性并不总是可用的——默认情况下,它不会打开。您的应用程序节点如何连接到消息队列?通过一个刷新连接池,或者使用一个短生命周期DNS记录,或者通过负载均衡器?队列可以有很多配置项和大小是多少,什么行为是(消费者需要不需要确认接受,要注重处理失败,多个消费者得到相同的消息,消息有TTL,等等)以及网络和消息传递开销,特别是现在每个人都喜欢与XML或JSON传递信息。如果过度使用消息队列,它将增加系统延迟。

最后但并非最不重要的是,如果出现问题,使用消息队列使问题跟踪非常困难。您不能在IDE中看到调用层次结构,因为一旦您将消息发送到队列,您就必须找到它正在处理的位置。这并不像听起来那么简单。你看,它增加了很多复杂性和很多值得注意的东西。

通常,消息队列在某些上下文中非常有用。当他们做的时候,我在项目中使用它们——例如,我们不想失去信息,但我们想要快速地做。我还看到它在一些不太常见的场景中使用,比如只使用一个应用程序节点,而不考虑交付哪个节点。您还可以查看stackoverflow上的问题。一些使用场景是,也许您确实需要更多的语言通信,或者您的数据流太复杂了,不要使用新的消息使用者,但是添加新的方法调用会花费很多。

如果您不确定是否没有其他更容易管理和维护的方法,请确保使用消息队列,最好不要使用。不要仅仅因为它有用就使用它——如果你真的想使用它。因为这是可能的,就像这个项目一样,消息队列不是真正必要的。

本文来自企鹅号 - 纵横动力成都基地媒体

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏王金龙的专栏

微服务入门

“微服务”最初是由 MartinFowler 在 2014年写的一篇文章 《MicroServices》中提出来的。 关于 Martin Fowler 的介绍,...

712
来自专栏ImportSource

NoSQL-Relaxing Durability-放宽“持久性”约束

作者简介: ? 有的小伙伴对于放宽“持久性”不屑一顾——他们认为如果数据库丢失了更新操作的能力那还叫数据库吗?然而。。。。。 5.4. Relaxing Dur...

3368
来自专栏Keegan小钢

App架构设计经验谈:数据层的设计

一个App,从根本上来说,就是对数据的处理,包括数据从哪里来、数据如何组织、数据怎么展示,从职责上划分就是:数据管理、数据加工、数据展示。相对应的也就有了三层架...

662
来自专栏Java架构沉思录

10分钟了解ZooKeeper

ZooKeeper是一个开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等。

842
来自专栏携程技术中心

开源 | 携程Redis多数据中心解决方案-XPipe

作者简介 孟文超,携程技术中心框架研发部高级经理。2016年加入携程,目前主要负责Redis多数据中心项目XPipe。此前曾在大众点评工作,任基础架构部门通信团...

36910
来自专栏后端技术探索

Nginx如何实现高性能和可扩展性

Owen Garrett是Nginx公司的产品总监,他在Nginx的官方博客上发表了一篇博文,说明了是哪些设计决策使得NGINX产品具备一流的性能和扩展能力。

491
来自专栏ImportSource

分布式下的MS

MS模式是分布式系统中非常重要的一种复制模式,为了和配图协调,请允许这里直接使用了master-slave的缩写,没错,MS! 好,从现在开始,我们的标题变为:...

2514
来自专栏服务端技术杂谈

微服务实践

什么是微服务 微服务的两个核心: 微:服务粒度更细,即服务要细到API 服务:提供好服务,让服务好用 总结以上两点,来看这张图: ? 从图可以看出,微服务很简单...

2904
来自专栏SDNLAB

OpenNF:驱动网络功能控制创新

1 介绍 网络功能(NFs),或中间件是以复杂方式检测和更改数据包和流的系统。比如:入侵检测系统(IDSs),负载均衡器,缓存代理等。NFs在确保安全性,提高...

3344
来自专栏nice_每一天

高并发与高可用实战之基础知识大型网站架构特征(一)

系统设计不仅需要考虑实现业务功能,还要保证系统高并发、高可用、高可靠等。同时还应考虑系统容量规划(流量、容量等)、SLA指定(吞吐量、响应时间、可用性、降级方案...

804

扫码关注云+社区