Zer*_*uno 10 rest spring tomcat rabbitmq kubernetes
我创建了一个REST API - 简而言之,我的客户端点击了一个特定的URL,然后她获得了一个JSON响应.
在内部,当URL被命中时,相当复杂的过程开始,并且在使用微服务架构时涉及各种服务.
我正在观察一些性能瓶颈,并决定切换到消息队列系统.现在的想法是,一旦用户点击URL,就会在内部消息队列上发布请求,等待它被消费.此消费者将处理并发布回队列,这将发生很多次,直到最后,为用户提供服务的同一节点将收到要传递给用户的已处理响应.
现在正在使用异步"即发即忘"模式.但我的问题是,一旦处理结果返回并且没有阻塞(即它可以处理多个请求直到收到响应),为特定人员服务的节点如何能够记住它正在服务的对象?如果它有任何区别,我的堆栈看起来有点像:TomCat,Spring,Kubernetes和RabbitMQ.
总之,请求节点(其作业是推送队列中的项目)如何与请求JSON响应的客户端保持开放连接(即客户端正在等待JSON响应)并接收正确客户端的数据?
根据您对客户端的控制程度,您有几种不同的方案。
如果无法更改客户端行为,则必须保持会话打开,直到请求尚未完全处理。这可以通过使用一个工作池(期货/协程、线程或进程)来实现,其中每个工作人员为给定的请求保持会话打开。
这种方法几乎没有缺点,我会将其作为最后的手段。首先,您将只能处理与池大小成比例的有限数量的并发请求。最后,由于您的处理在队列后面,您的前端将无法估计完成任务需要多长时间。这意味着您将不得不处理容易失败的持久会话(如果用户放弃怎么办?)。
如果可以更改客户端行为,最常见的方法是使用完全异步的流程。当客户端发起请求时,它被放置在队列中并返回一个任务标识符。客户端可以使用给定TaskId来轮询状态更新。每次客户端请求有关任务的更新时,您只需检查它是否已完成并做出相应的响应。当任务仍在进行中时,一个常见的模式是让前端在重试之前返回给客户端估计的时间量。这允许您的服务器控制客户端轮询的频率。如果您的架构支持它,您可以加倍努力并提供有关进度的信息。
任务正在进行时的示例响应:
{"status": "in_progress",
"retry_after_seconds": 30,
"progress": "30%"}
Run Code Online (Sandbox Code Playgroud)
一个更复杂但更优雅的解决方案是使用 HTTP 回调。简而言之,当客户端请求新任务时,它会提供一个元组(URL、方法),服务器可以使用它来表示处理已完成。然后它等待服务器将信号发送到给定的 URL。你可以在这里看到更好的解释。在大多数情况下,这种解决方案是矫枉过正的。不过我觉得还是值得一提的。
| 归档时间: |
|
| 查看次数: |
628 次 |
| 最近记录: |