【问题标题】:Can I throttle requests made by a distributed app?我可以限制分布式应用程序发出的请求吗?
【发布时间】:2011-01-20 17:42:43
【问题描述】:

我的应用程序发出 Web 服务请求;提供者将处理的请求有一个最大速率,所以我需要限制它们。

当应用程序在单个服务器上运行时,我曾经在应用程序级别执行此操作:一个跟踪到目前为止已发出多少请求的对象,并在当前请求使其超过允许的最大负载时等待.

现在,我们正在从单个服务器迁移到集群,因此有两个应用程序副本正在运行。

  • 我无法继续检查应用程序代码中的最大负载,因为两个节点的组合可能会超过允许的负载。
  • 我不能简单地减少每台服务器的负载,因为如果另一个节点空闲,第一个节点可以发出更多请求。

这是一个 JavaEE 5 环境。限制应用程序发出的请求的最佳方法是什么?

【问题讨论】:

  • 只是好奇,你使用的是像 Terracota 这样的特殊框架吗?
  • @Pablo:不。我们正在从专用服务器上的单个 JBoss 服务器迁移到配置有两个节点的托管 WebLogic 10.3。

标签: java jakarta-ee throttling


【解决方案1】:

由于您已经处于 Java EE 环境中,因此您可以创建一个 MDB 来处理基于 JMS 队列的 Web 服务的所有请求。应用程序的实例可以简单地将它们的请求发布到队列中,MDB 将接收它们并调用 Web 服务。

队列实际上可以配置适当数量的会话,这将限制对您的 web 服务的并发访问,因此您的限制是通过队列配置处理的。

结果可以通过另一个队列(甚至每个应用程序实例一个队列)返回。

【讨论】:

  • 是的,因为我已经在 J​​avaEE 环境中,JavaEE 队列是最直接的解决方案,我不需要添加任何其他依赖项。
【解决方案2】:

N 个节点需要通信。有多种策略:

  • 广播:每个节点都会向其他所有人广播它正在呼叫,所有其他节点都会考虑到这一点。节点是平等的,并保持单独的全局计数(每个节点都知道每个其他节点的调用)。
  • 主节点:一个节点是特殊的,它的主节点和其他所有节点在调用之前都请求主节点的许可。主人是唯一知道全局计数的人。
  • dedicated master:与master相同,但“master”本身不做调用,只是一个跟踪调用的服务。

根据您预计以后扩展的高度,一种或另一种策略可能是最好的。对于 2 个节点,最简单的一个是广播,但随着节点数量的增加,问题开始出现(与实际执行 WS 请求相比,您将花费更多时间广播和响应广播)。

节点如何通信,由您决定。你可以打开一个 TCP 管道,你可以广播 UDP,你可以单独为此目的做一个成熟的 WS,你可以使用文件共享协议。无论您做什么,您现在都不再处于进程中,因此所有fallacies of distributed computing 都适用。

【讨论】:

    【解决方案3】:

    这样做有很多方法:您可能有一个“协调代理”,负责将“令牌”交给服务器。每个“令牌”代表执行任务等的权限。每个应用程序都需要请求“令牌”才能进行调用。

    一旦应用程序耗尽其令牌,它必须在再次访问 Web 服务之前要求更多。

    当然,当每个应用程序由于对 Web 服务的并发性而对每个调用的时间有要求时,这一切都会变得复杂。

    您可以依赖 RabbitMQ 作为消息传递框架:Java 绑定可用。

    【讨论】:

    • +1 因为我不知道 RabbitMQ 也有 .net 绑定。​​
    【解决方案4】:

    我建议使用beanstalkd 定期将一组请求(作业)泵入管道(队列),每个请求都有适当的延迟。任何数量的“工作”线程或进程都将等待下一个可用请求,如果工作人员提前完成,它可以接收下一个请求。不利的一面是工作人员之间没有任何明确的负载平衡,但我发现队列外的请求分布已经很好地平衡了。

    【讨论】:

      【解决方案5】:

      这是一个有趣的问题,解决的难度在一定程度上取决于您希望对节流有多严格。

      我通常的解决方案是JBossCache,部分原因是它与 JBoss AppServer 打包在一起,但也因为它可以很好地处理任务。您可以将其用作一种分布式哈希图,以不同的粒度记录使用情况统计信息。可以异步进行更新,因此不会减慢速度。

      JBossCache 通常用于重型分布式缓存,但我也更喜欢它用于这些轻量级的工作。它是纯 java,不需要与 JVM 混在一起(不像 Terracotta)。

      【讨论】:

        【解决方案6】:

        Hystrix 专为您所描述的场景而设计。您可以为每个服务定义线程池大小,这样您就可以设置最大并发请求数,并在池已满时将请求排队。您还可以为每个服务定义超时,当服务启动超过其超时时,Hystrix 将在短时间内拒绝对该服务的进一步请求,以便让服务有机会重新站起来。还可以通过Turbine实时监控整个集群。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-17
          • 2021-11-23
          • 1970-01-01
          • 2021-09-20
          • 2020-03-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多