【问题标题】:Front-facing REST API with an internal message queue?带有内部消息队列的前端 REST API?
【发布时间】:2019-04-30 16:52:07
【问题描述】:

我创建了一个 REST API - 简而言之,我的客户点击了一个特定的 URL,她得到了一个 JSON 响应。

在内部,当 URL 被点击时,一个相当复杂的过程开始了,并且在使用微服务架构时涉及到各种服务。

我观察到一些性能瓶颈并决定切换到消息队列系统。这个想法是,现在,一旦用户点击 URL,就会在内部消息队列上发布一个请求,等待它被使用。该消费者将处理并发布回队列,这将发生很多次,直到最后,为用户提供服务的同一节点将收到处理后的响应以传递给用户。

现在正在使用异步“即发即弃”模式。但我的问题是,一旦处理的结果返回并且没有阻塞(即它可以处理多个请求直到收到响应),为特定人提供服务的节点如何记住它正在为谁服务?如果有什么不同的话,我的堆栈看起来有点像这样:TomCat、Spring、Kubernetes 和 RabbitMQ。

总而言之,请求节点(其工作是向队列中推送项目)如何与请求 JSON 响应(即客户端正在等待 JSON 响应)的客户端保持开放连接并接收返回的数据正确的客户?

【问题讨论】:

  • 您是否可以选择 a) 使用非阻塞调用,以便您可以照常处理另一个请求,而当前请求正在等待来自后端微服务的响应,b) 返回客户端任务 ID 令牌以便她稍后可以在任务准备就绪后查询任务结果(从而维护任务 ID 到 response-json 映射?
  • 是的,两者都是我的选择

标签: spring rest tomcat kubernetes rabbitmq


【解决方案1】:

根据您对客户端的控制程度,您有几个不同的场景。

如果无法更改客户端行为,您将不得不保持会话打开,直到请求未被完全处理。这可以通过使用一组工作人员(期货/协程、线程或进程)来实现,其中每个工作人员为给定的请求保持会话打开。

这种方法几乎没有缺点,我会保留它作为最后的手段。首先,您将只能处理与您的池大小成比例的有限数量的并发请求。最后,由于您的处理在队列后面,您的前端将无法估计完成任务需要多长时间。这意味着您将不得不处理容易失败的长时间会话(如果用户放弃了怎么办?)。

如果可以更改客户端行为,最常见的方法是使用完全异步的流程。当客户端发起一个请求时,它被放置在队列中并返回一个任务标识符。客户端可以使用给定的TaskId 来轮询状态更新。每次客户请求更新任务时,您只需检查它是否已完成并做出相应的响应。任务仍在进行中的常见模式是让前端在重试之前将估计的时间返回给客户端。这允许您的服务器控制客户端轮询的频率。如果您的架构支持它,您可以加倍努力并提供有关进度的信息。

任务进行中的响应示例:

{"status": "in_progress",
 "retry_after_seconds": 30,
 "progress": "30%"}

更复杂但更优雅的解决方案是使用 HTTP 回调。简而言之,当客户端请求新任务时,它提供了一个元组(URL,方法),服务器可以使用它来表示处理完成。然后它等待服务器将信号发送到给定的 URL。你可以看到更好的解释here。在大多数情况下,这种解决方案是多余的。但我认为值得一提。

【讨论】:

  • 感谢您的详细回答。它涵盖了我几乎从 A 到 Z 的问题。我希望它会有更多关于图书馆的信息,例如Spring / Java / RabbitMQ 将如何处理您所指的工人池?否则,它帮助我非常详细地掌握了这个概念,所以谢谢。
  • 很遗憾,我对 Java/Spring 环境并不熟悉。对于第一种方法,搜索的关键字通常是:futuresdeferredasynchronousworkers pool。第二种和第三种方法对于 REST 基础架构很常见,并且非常易于实现。我不知道 Java/Spring 是否在它之上提供了任何抽象,但它是一个非常简单的概念,您可以自己实现它。
【解决方案2】:

一种选择是使用 spring 提供的 DeferredResult ,但这意味着您需要在请求服务节点中维护一些线程池和最大数量。活动线程的数量将决定系统的吞吐量。有关如何实现 DeferredResult 的更多详细信息,请参阅此链接https://www.baeldung.com/spring-deferred-result

【讨论】:

    猜你喜欢
    • 2016-11-21
    • 2021-09-30
    • 2013-03-10
    • 2020-07-09
    • 1970-01-01
    • 2017-09-11
    • 2021-09-12
    • 1970-01-01
    • 2020-11-17
    相关资源
    最近更新 更多