2010-02-24 53 views
10

我的应用程序发出Web服务请求;有一个供应商将处理的请求的最大速度,所以我需要扼杀他们。我可以限制分布式应用程序提出的请求吗?

当应用程序在一台服务器上运行,我用在应用层面做到这一点:持续跟踪多少请求迄今取得的对象,并等待如果当前的请求使得它超过了允许的最大值加载。

现在,我们正在从一个单一的服务器群集迁移,所以有运行应用程序的两个副本。

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

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

+2

只是好奇,你使用像Terracota这样的特殊框架吗? – 2010-02-24 21:21:21

+0

@Pablo:不。我们正在从专用服务器上的单个JBoss服务器迁移到配置了两个节点的托管WebLogic 10.3。 – Leonel 2010-02-25 01:28:07

回答

5

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

该队列实际上可以配置适当数量的会话,这会限制并发访问您的webservice,因此您的限制通过队列配置来处理。

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

+0

是的,因为我已经在JavaEE环境中,所以JavaEE队列是最直接的解决方案,我不需要添加任何其他依赖项。 – Leonel 2010-03-08 13:52:01

1

许多这样做的方法:你可能有一个“协调代理”,这是负责的移交“令牌”的服务器。每个“令牌”表示执行任务等的权限。每个应用程序需要请求“令牌”以发出呼叫。

一旦应用程序耗尽它的令牌时,必须在继续又打了Web服务之前要求更多一些。

当然,这一切又当有与问候每个应用使得对,因为Web服务的并发调用每一个的时序要求复杂。

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

+0

+1,因为我不知道也有.net绑定的RabbitMQ。 – tobsen 2010-02-24 22:35:04

1

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

  • 广播:每个节点将广播给其他人,它正在呼叫一个电话,所有其他节点将考虑到这一点。节点是相等的并且保持个别的全局计数(每个节点知道每个其他节点的呼叫)。
  • 主节点:一个节点是特殊的,其主节点和所有其他节点在进行呼叫前向主节点请求许可。主人是唯一知道全球人数的人。
  • 专用主:同主人,但“主”的itslef没有做电话,仅仅是跟踪电话的服务。

根据您预计稍后放大多少,一个或另一个策略可能是最好的。对于2个节点,最简单的节点是广播节目,但随着节点数量的增加,问题开始出现(你将花费更多的时间来广播和响应广播,而不是实际执行WS请求)。

节点之间的沟通方式取决于你。你可以打开一个TCP管道,你可以广播UDP,你可以单独为这个目的做一个完全成熟的WS,你可以使用文件共享协议。无论您做什么,您现在都不再处于流程中,因此所有fallacies of distributed computing都适用。

1

这是一个有趣的问题,解决方案的难度取决于您希望节流的程度。

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

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

2

我建议使用beanstalkd定期将一系列请求(作业)抽成管(队列),每个请求(作业)都有适当的延迟。任何数量的“工人”线程或进程都会等待下一个请求可用,并且如果工作者提前结束,它可以接收下一个请求。不利的一面是工人之间没有任何明确的负载平衡,但我发现请求的队列分配非常均衡。

0

Hystrix专为您描述的确切场景设计。您可以为每个服务定义一个线程池大小,以便设置最大数量的并发请求,并在池满时对请求进行排队。您还可以为每个服务定义一个超时,并且当服务开始超过超时时间时,Hystrix会在短时间内拒绝对该服务的更多请求,以便让服务有机会恢复原状。还有通过Turbine实时监控整个群集。

相关问题