【问题标题】:distributed pool with limited size大小有限的分布式池
【发布时间】:2014-08-21 11:15:53
【问题描述】:

有一个系统可以访问各种效率不高的服务。服务被调用作为处理一些消息的结果。 由于这种低效率,系统被限制为每个节点 1 个消息消费者 - 以避免使特定服务“A”过载。处理的消息会有所不同,并且可能会同时处理多条消息,所有消息都需要调用服务“A” - 因此存在限制。假设服务“A”可以处理 3 个并发连接,系统有 3 个节点,因此每个节点允许的最大消费者数为 1。

其他服务也有自己的容量,从说的3到基本无限制。

问题是 - 引入此类限制的最佳方式是什么?如果只有一个节点,只需引入一个服务客户端池就很容易了。当然,它会阻止消息消费者,直到客户端可用,但可以忍受它。但这也意味着每个节点大小为 1 的池(因为所有 3 个节点都可以开始调用服务“A”)。 对于多个节点,需要某种分布式客户端池。有这样的吗?

(我知道,如果将单个消息处理拆分为较小的消息,每个服务调用 1 个,则允许使用 JMS 队列来执行此操作,但由于消息处理的事务性质,它不可行)。

【问题讨论】:

  • 阿帕奇骆驼? EIP 框架实施。节流模式或许能解决您的问题 - camel.apache.org/throttler.html
  • 您要归档的内容不是很清楚。据我所知,您需要 2 个信号量,每个服务一个“全局”限制服务的连接总数,一个限制每个节点的连接数量?
  • 只是一个全局“信号量”,限制每个服务的传出连接数

标签: java message-queue connection-pooling distributed


【解决方案1】:

我看到了两种可能的解决方案。两者都基于解决问题的中间件方法,其中简单的解决方案可以解决您的特定问题,而更高级的解决方案需要更大的投资才能获得更大的灵活性和额外的好处。

简单的代理解决方案

在效率不高的服务前创建自己的中间件代理。代理将维护到后端服务的有限连接池。然后,当与后端服务的出站连接被阻塞时,只需阻止或拒绝(而不是队列)。否则只需将来自入站系统节点的请求转发到后端服务,然后用服务的响应响应系统节点。这样后端服务永远不会超载。它允许您的节点由于它们的事务性质而需要的同步通信。

系统架构师解决方案

使用功能齐全的 ESB(企业服务总线)。一种允许您对特定端点的并发连接设置限制,并允许异步和同步消息处理。然后,ESB 成为您的环境范围的流量控制器,可以将其配置为在效率不高的端点阻塞时阻止或拒绝消息。要获得更多好处,请寻找允许服务质量配置的 ESB,以防止在使用有限资源时系统节点出现饥饿,或自动重试连接到不稳定端点的尝试。

【讨论】:

  • 简单的解决方案不起作用 - 它只会将问题从“我的”集群转移到服务(或代理服务)及其集群。另外我需要实现 30 个代理 :) ESB 已经到位,它实际上可能是解决部分问题的好方法。不幸的是,它在某些情况下不起作用,因为该 ESB 不支持某些服务(不是 Web 服务 - 部署在大型机上并使用特定的二进制协议)
  • 简单代理并不意味着是一个集群。因此,问题从多节点转移到单节点设置,您自己说这很容易。这个想法是充当问题服务的门面,考虑到我假设的限制也不是集群,因此几乎不会丢失冗余或可用性。此外,您不需要代理来获得基本无限制的服务。因此,除非您有 30 个问题服务,否则它可能会更少。 Web 服务可以由现有的代理软件处理,例如具有连接限制的 Apache/mod_proxy。不必从头开始创建它们。
  • 简单的代理解决方案看起来不错,即使从异步/队列通信的角度来看,具有冗余后端也是如此。我在这样的环境下工作,但没有中间件代理,如果发生中断,这很麻烦:如果前端服务器出现故障,剩余的前端服务器可能会增加它们对慢速服务的负载(吞吐量保持在同样),如果后端服务器出现故障,所有前端服务器都需要减少慢速服务的负载(吞吐量下降)。中间件代理可以协调这一点(实现起来可能并不简单,但绝对有可能)。
猜你喜欢
  • 1970-01-01
  • 2014-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-04
  • 2016-07-10
  • 1970-01-01
相关资源
最近更新 更多