【问题标题】:How to handle long-running unstable server如何处理长时间运行的不稳定服务器
【发布时间】:2020-04-03 06:04:10
【问题描述】:

我们有一个不稳定的旧单体系统,95% 的请求在 500 毫秒内处理,但其他 5% 需要 > 10 秒并且连接超时。我想让我们的服务更有弹性。通过 REST 和architecture is like this 进行通信。

我们当前的方法是使用具有指数退避重试机制的异步 http 客户端。但这会随着流量的增加而导致性能问题

我的想法是在 S 中进行同步 http 调用,超时时间为 500 毫秒,并使用一种后备方法将任务添加到队列中,以便将来重试 http 请求,同时将 202 连同指向的链接一起返回给 C检查任务的状态,例如/queue/task-123。我知道我需要让 S 暴露给 C 的服务是幂等的,所以每次收到来自 C 的新请求时我都必须检查队列,以确保我没有重复的任务。

问题:

  1. 有没有更好的方法来解决我的问题?
  2. 队列中的任务是在 REST 端点中处理重试的最佳方式吗?

我们的堆栈:使用 Spring 引导的 Java 和我认为是 RabbitMQ 的队列

【问题讨论】:

  • 我知道真正的解决方案是解决根本问题,但我的目标是使服务尽可能具有弹性。与其说是如何解决问题,不如说是如何在未来保护自己免受此类事件的影响。
  • 当您说 95% 正常而 5% 不正常时,服务器是否经历了所有请求超时然后服务器恢复并且所有请求再次正常的时期,或者您是否得到即使在同一时间的其他请求都很好,但偶尔的单个请求也会超时?
  • @ChrisC 其他请求都很好,但是这个请求需要很长时间。但正如我所说,这不是问题的重点。我想要实现的是增加服务的弹性,而不是解决根本问题。
  • 好的,但是在重试处理方面了解它可能是有用的信息。我认为您建议的方法是可以的,但您也可以考虑回调,而不是客户端必须轮询端点。队列上的任务是一种很好的方法,因为它可以阻止客户端无休止地重试,而您只是承诺在您到达它时会到达它们。您将需要对任务进行重复检查,但我对 RabbitMQ 的了解还不够,无法知道您是否可以询问队列中的消息以比较有效负载...也许是最近 msg 哈希的数据库?

标签: java spring spring-boot architecture


【解决方案1】:

让对 S 的请求为 AsyncHttpResponse 创建 Futures,并将它们发送到具有足够大的线程池以容纳您的负载的 Executor,但不要太高以至于它会淹没您的 Monolith。这样当事情开始失败时,它就不会滚雪球了,其他请求可以排队。您仍然可以在此模型中使用重试模型,但要在将来对其进行控制,以便在重试之前允许成功的请求进入。

【讨论】:

    猜你喜欢
    • 2011-01-19
    • 1970-01-01
    • 2013-10-19
    • 1970-01-01
    • 2017-08-24
    • 2019-06-06
    • 1970-01-01
    • 1970-01-01
    • 2012-04-10
    相关资源
    最近更新 更多