你真的需要消息队列吗

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏企鹅号快讯

利用Django在前端展示Oracle 状态趋势

开发环境 操作系统:CentOS 7.4 Python版本 :3.6 Django版本: 1.10.5 操作系统用户:oms 数据处理:pandas 前端展示:...

2897
来自专栏日常学python

30行Python代码实现自动收发邮件

生活或者工作中我们经常容易忘记一些事情,这时候我们需要借助一些事物来提醒我们。读者中应该有很多运维攻城狮和测试攻城狮,服务器有异常时需要提醒我们,自动化测试执行...

1193
来自专栏互联网技术栈

Tair数据迁移三步走

在多机房数据迁移中,整个过程分为三个阶段:历史数据迁移阶段、redolog迁移阶段、实时复制阶段。

1003
来自专栏北京马哥教育

必看!深入理解linux系统的目录结构就靠本文了

本文由马哥教育面授班24期学员推荐,转载自互联网,作者为郭東,内容略经小编改编和加工,观点跟作者无关,最后感谢作者的辛苦贡献与付出。 Linux和Windows...

4487
来自专栏我的博客

scp命令提示bash:scp command not found

今天需要从a主机拷贝文件到b主机,两个主机都是linux的。 在a主机上使用scp命令拷贝 scp /root/1.txt root@www.0377joyou...

2935
来自专栏运维技术迷

chattr命令

chattr命令用来改变文件属性。这项指令可改变存放在ext2/3/4文件系统上的文件或目录属性。 一、文件或目录属性 1.1 属性 这些属性共有以下8种模式...

3345
来自专栏架构师之路

TCP接入层的负载均衡、高可用、扩展性架构

一、web-server的负载均衡 ? 互联网架构中,web-server接入一般使用nginx来做反向代理,实施负载均衡。整个架构分三层: 上游调用层,一般是...

4226
来自专栏小特工作室

基于Ado.Net的日志组件

软件开发,离不开对日志的操作,它可以帮助我们查找和检测问题。好的日志组件可以对于整个系统来说,至关重要 在NaviSoft产品中,日志组件也占有非常重要的份量。...

2109
来自专栏步履前行

Java基础系列---Java平台上的一些问题

  从学习Java开始,我们接触了许多框架,从Hibernate、Strus、Strus2、Spring、Spring MVC、Spring boot等等,做J...

761
来自专栏PHP在线

单点登录方案[学习]

引子 昨天在网上看到一个帖子,帖子的内容大概是说领导要求一个苦B程序员实现一个单点登录的系统,将各个业务系统联系起来,但不能修改其他业务系统的源码。 其实,在企...

40815

扫码关注云+社区