我的应用程序发出Web服务请求;提供商将处理的请求的最大速率,因此我需要限制它们。
当应用程序在单个服务器上运行时,我曾经在应用程序级别执行此操作:跟踪到目前为止已经发出了多少请求的对象,并等待当前请求是否超过允许的最大负载量
现在,我们正在从单个服务器迁移到群集,因此有两个应用程序副本正在运行。
这是一个JavaEE 5环境。限制应用程序发出请求的最佳方法是什么?
答案 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)