【问题标题】:How to properly throttle web requests to external systems?如何正确限制对外部系统的 Web 请求?
【发布时间】:2013-08-26 04:58:42
【问题描述】:

我的 Java Web 应用程序从外部系统(基于 HTTP 的 JSON)提取一些数据,无论何时我的应用程序的用户请求它和批处理(对于没有用户请求它的情况,每晚更新)都是实时的。数据发生变化,因此缓存选项可能已用尽。

外部系统有一些限制,我不知道确切的参数,并且可能会根据系统负载而变化(例如,峰值时间每秒来自一个 IP 地址的 10 个请求,非峰值时间 100来自开放 IP 地址的每秒请求数)。如果请求过于频繁,它们会超时或返回 HTTP 503。

现在我正在尝试请求 5 次,每次之间有 2000 毫秒的延迟,如果每次都收到错误则放弃。这不是最优的,因为有时在高峰时间几乎所有请求都会失败;我可以避免提出这些请求,并且至少可以让一些请求成功。

我的目标是拥有一个简单、可靠的设计和足够的灵活性,以便我可以从节流器中提取一些指标来了解外部系统的响应情况(从而调整它们被调用的频率),并且自动调整我调用它们的时间间隔(每个系统单独调整),以便在非高峰时段和高峰时段都达到最佳状态。

我的基础架构是 Java 和 RabbitMQ over MongoDB over Linux。

我正在考虑三个主要选项:

  1. 由于我已经将 RabbitMQ 用于批处理,我可以只引入一个队列,Web 进程会将它们对外部系统的请求发送到该队列,然后工作进程将从该队列中读取数据,并根据需要限制自己,并返回结果。如果需要,这将允许在更多服务器上运行多个并行工作进程。我主要担心的是它不是一个非常简单的解决方案,以及如何管理高峰时段的吞吐量很低,因此 Web 进程等待很长时间。这也将我的 RabbitMQ 转换为一个关键的单一故障点;如果它死了,整个系统就会停止(与夜间批处理相反,它不再运行,这不太重要)。我想rpc 是 RabbitMQ 使用的正确模式,但不确定。编辑 - 我已经发布了一个相关的问题How to properly implement RabbitMQ RPC from Java servlet web container?,关于如何实现这一点。

  2. 引入 nginx(例如ngx_http_limit_req_module)、HAProxy(link)或其他代理软件(作为反向代理?),让他们通过一些配置魔法来处理节流。优点是我不必更改代码。缺点是它使用了更多技术,而且我以前没有使用过,因此错误配置某些东西的可能性很高。根据外部服务器负载进行动态限制,或将实时请求优先于批处理请求,或获取限制如何进行的统计数据也可能并不容易。此外,大多数文档和示例可能会限制传入请求,而不是传出请求。

  3. 执行纯 Java 解决方案(例如,漏桶实现)。从“只是代码”的意义上说,这很简单,但魔鬼在细节中;调试所有的死锁、饥饿和竞争条件并不总是很有趣。

我在这里缺少什么?

在这种情况下,最好的解决方案是什么?

附:一些相关的问题 - 记录所有外部系统调用的正确方法是什么,以便收集关于我调用它们的频率以及成功率的统计信息?

例如,在每次调用之后,我都会调用类似 .logExternalSystemInvocation(externalSystemName, wasSuccessful, elapsedTimeMills) 的内容,然后在需要时从中获取一些聚合数据。

是否有标准库/工具可供使用,还是我必须自己开发?

如果我将选项 1. 与 RabbitMQ 一起使用,有没有办法组织流程,以便我从 RabbitMQ 控制台开箱即用?我不想将所有失败的消息发送到毒队列,但它会很快填满,并且在大多数情况下,由于用户已经遗憾地继续前进,因此无需重新处理这些失败的请求。

【问题讨论】:

  • The data changes so caching options are likely exhausted.,我们正在处理什么样的变化?对于不同的用户,它是唯一的吗?还是喜欢基于时间的?
  • 外部系统跟踪有关特定对象的信息。这些信息会随着时间而改变。我已经在每个对象级别进行缓存,仅当有关特定对象的信息在最后 X 分钟内未刷新时才转向外部系统。无论如何,虽然更智能的缓存可能会或可能不会有帮助,但我不希望它成为这个问题的焦点。
  • 有趣的问题。在处理第三方 api 时,我们正在努力解决这个确切的问题。 API 限速策略未知。你找到了解决这个问题的好办法吗?

标签: java nginx rabbitmq throttling


【解决方案1】:

或许这个开源系统可以帮到你一点:http://code.google.com/p/valogato/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-28
    • 1970-01-01
    • 2012-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多