Spring cloud stream 流应用程序中的瓶颈导致消息丢失 用于CloudFoundry v1.4.x的Spring云数据流(SCDF)服务器 为消息传输配置的RabbitMQ服务磁贴

Spring cloud stream 流应用程序中的瓶颈导致消息丢失 用于CloudFoundry v1.4.x的Spring云数据流(SCDF)服务器 为消息传输配置的RabbitMQ服务磁贴,spring-cloud-stream,spring-cloud-dataflow,Spring Cloud Stream,Spring Cloud Dataflow,部署的spring云数据流具有一个处理器,该处理器可以比下游处理器或接收器处理传入消息更快地生成传出消息。这导致RabbitMQ传输出现瓶颈,最终导致消息丢失 在我们的私有云环境中,Rabbit服务磁贴的默认设置为max length=1000和max length bytes=1000000。我们目前无法修改这些设置以增加这些容量 我们已经尝试在消费应用程序上设置prefetch值(我相信设置应该是deployer..rabbit.bindings.consumer.prefetch=1000

部署的spring云数据流具有一个处理器,该处理器可以比下游处理器或接收器处理传入消息更快地生成传出消息。这导致RabbitMQ传输出现瓶颈,最终导致消息丢失

在我们的私有云环境中,Rabbit服务磁贴的默认设置为
max length=1000
max length bytes=1000000
。我们目前无法修改这些设置以增加这些容量

我们已经尝试在消费应用程序上设置
prefetch
值(我相信设置应该是
deployer..rabbit.bindings.consumer.prefetch=10000
),这似乎实际上增加了消费应用程序在较短时间内消费更多消息的能力,但这只在有限的情况下有效。如果我们有一个非常大的数据量通过流,我们仍然有可能达到一个限制,消息被丢弃。在上面的示例中,我们似乎通过设置预取将消费应用程序的容量从1000增加到11000

我们还尝试使用自动伸缩服务,因此我们可以增加消费应用程序的活动实例数量,这也可以明显增加其容量。然而,这似乎也解决了带创可贴的问题,而不是使用固有的能够以弹性方式处理潜在体积期望的基础设施和/或服务。如果我们不知道一天中的特定时间卷将显著增加,如果卷的增长速度使自动定标器设置中的CPU阈值无法足够快地跟上活动实例以避免丢失消息,该怎么办

  • 我们尚未尝试将RabbitMQ服务设置为保证交付。根据文档,似乎更容易判断消息何时未送达,而不是确定是否送达。我们不知道这是否是一个好的可行选择,正在寻求建议
  • 我们还没有尝试在流应用程序本身中实现任何节流。我们不知道这是否是一个好的可行选择,正在寻求建议
  • 我们没有尝试将应用程序绑定到DLQ或对处理失败的消息重新排队。我们不知道这是否是一个好的可行选择,正在寻求建议
  • 我们还没有尝试将SCDF服务器绑定到云铸造服务之外的我们自己的Rabbit服务实例。从理论上讲,这将是一个RabbitMQ实例,我们可以对队列深度和字节大小限制进行更多控制,从而可以将它们设置为更容易地处理预期负载
  • 我们还没有尝试过像卡夫卡这样的替代运输机制。我们不知道这是否是一个好的可行选择,正在寻求建议
我很难相信其他人在这些流模式中没有遇到类似的问题,我很好奇是否有一个公认的最佳实践解决方案,或者我们是否需要更仔细地观察流模式是否在这些情况下被误用

我们的基本要求是,在任何流式应用程序上下文中丢失消息都是不可接受的情况,我们需要确定配置环境的最佳方法,或分析实现选择,以确保实现在重负载下的健壮性和可靠性

社区或关键人物对此有什么建议吗?

Channing

感谢您提供了如此多的细节、问题以及您对Spring Cloud Stream和SCDF的兴趣,但我希望您理解,这并不是一个真正的问题,因为它有如此多的变量,不可能有答案,更适合于某种类型的讨论。也许是GitHub中针对上述任一项目的功能请求,我们可以在那里进行讨论。 无论如何,我会尽我所能确保它不会无人回答

你所问的是背压,事实上这是一个非常有效的问题。然而,需要了解的是,Spring Cloud Stream和随后的SCDF选择支持多个消息传递系统/协议(通过绑定器)来将微服务连接在一起,而不是创建我们自己的服务。而且,并非每个消息传递系统/协议都支持背压,而背压提供了实现背压的不同机制,因此很难/不可能在框架级别提供某种通用抽象

因此,它实际上更像是一个架构/设计讨论,我很乐意参与其中,但需要更多的上下文。 例如,在RabbitMQ的上下文中,生产者可以轮询队列大小(
RabbitAdmin.queueProperties(queue)
),并在超过某个阈值时停止发布。但正如我所说的,还有更多的技巧和方法,我们肯定需要更多的背景

我还应该提到,我们正在研究RSocket活页夹,这是一个系统和协议,本机支持背压


我希望这有助于

谢谢你的跟进。我很感激你把这看作是一个讨论而不是一个问题,我当然同意这一点。如果可以的话,还有一个问题——我昨天做了一个关于如何访问RabbitAdmin的小研究,这样我就可以检查我的流应用程序的传出通道,结果是空的。你对此有什么指导吗?