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

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

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

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

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

有帮助吗?

解决方案

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

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

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

其他提示

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

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

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

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

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

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

  • 播送:每个节点都会向其他所有人广播它正在拨打电话,并且所有其他节点都会考虑到这一点。节点是平等的并维护单独的全局计数(每个节点都知道其他节点的调用)。
  • 主节点:一个节点是特殊的,它是主节点,所有其他节点在进行调用之前都会请求主节点的许可。大师是唯一知道全局计数的人。
  • 专用大师:与 master 相同,但“master”本身不进行呼叫,只是一个跟踪呼叫的服务。

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

节点如何通信取决于您。你可以打开一个 TCP 管道,你可以广播 UDP,你可以单独为此目的做一个成熟的 WS,你可以使用文件共享协议。无论您做什么,您现在都不再处于流程中,因此所有 分布式计算的谬误 申请。

这是一个有趣的问题,解决方案的难度在一定程度上取决于你想要对限制有多严格。

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

JBossCache 通常用于重型分布式缓存,但我也更喜欢它用于这些轻量级作业。它是纯 java,不需要对 JVM 进行任何操作(与 Terracotta 不同)。

海斯特里克斯 几乎是为您所描述的场景而设计的。您可以为每个服务定义线程池大小,以便设置最大并发请求数,并在池已满时对请求进行排队。您还可以为每个服务定义一个超时,当某个服务开始超过其超时时,Hystrix 将在短时间内拒绝对该服务的进一步请求,以便让该服务有机会恢复正常。还可以通过以下方式实时监控整个集群 涡轮.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top