我可以限制分布式应用程序发出的请求吗?

时间:2010-02-24 21:16:31

标签: java java-ee throttling

我的应用程序发出Web服务请求;提供商将处理的请求的最大速率,因此我需要限制它们。

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

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

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

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

6 个答案:

答案 0 :(得分:5)

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

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

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

答案 1 :(得分:2)

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

答案 2 :(得分:1)

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

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

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

您可以依赖 RabbitMQ 作为Messaging框架:Java绑定可用。

答案 3 :(得分:1)

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

  • 广播:每个节点都会向其他人广播它正在调用一个呼叫,而所有其他节点都会将其考虑在内。节点是相同的并且保持单独的全局计数(每个节点都知道每个其他节点的呼叫)。
  • 主节点:一个节点是特殊节点,其主节点和所有其他节点在打电话之前请求主节点的许可。主人是唯一知道全球统计数的人。
  • 专用主人:与主人一样,但是'主'不对其进行呼叫,只是一个跟踪通话的服务。

根据您预期稍后扩展的程度,一种或另一种策略可能是最佳的。对于2个节点,最简单的节点是广播的,但随着节点数量的增加,问题开始增加(你将花费更多的时间来广播和响应广告,而不是实际的WS请求)。

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

答案 4 :(得分:1)

这是一个有趣的问题,解决方案的难度取决于您希望对限制的严格程度。

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

JBossCache通常用于重型分布式缓存,但我更喜欢这些轻量级的工作。它是纯粹的java,并且不需要使用JVM(与Terracotta不同)。

答案 5 :(得分:1)

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