如何处理长AJAX请求-发送响应但继续工作

本文关键字:-发 响应 工作 继续 请求 AJAX 何处理 处理 | 更新日期: 2023-09-27 18:17:28

我们正在使用jquery-ajax将指令集从浏览器发送到多层web应用程序。第一个组件(组件A,用c#编写)验证指令并将其持久化到数据库中,然后调用第二个组件(组件B,用Java编写,也通过HTTP调用),该组件在从同一数据库检索指令后对其进行操作。浏览器客户端在提交作业后仅通过组件A轮询rdbms表,因此在发送请求后它实际上是断开连接的,并且不等待组件A的响应。

中间层(组件A)向客户端返回成功消息,确认成功提交任务,但仍然向任务处理程序(组件B)发出请求并释放其所有资源的最佳方法是什么?返回响应是页面的最终操作,所以我们必须在将其发送回浏览器之前在另一个线程中做一些事情。

我们考虑的另一种选择是在组件B中发生这种情况,其中任务处理程序向中间层发送立即响应以确认请求,但随后继续在后台工作。唯一的区别是我们在哪里生成额外的线程来完成这项工作。

关于如何处理这个问题,有什么好主意吗?

如何处理长AJAX请求-发送响应但继续工作

可以通过生成线程来手动处理这种情况。但是您将面临的一个主要问题(我在编程经验中也遇到过)是,如果处理不当,线程有点难以维护,并且有几个缺点。首先,错误处理能力是有限的,您必须有一个外部表(持久化表)或一个全局变量来记录或捕获所有这些错误。另一个问题是服务器所能承受的处理限制。如果你在后台产生太多的线程,服务器的处理限制,因此它同时发出的数据库请求将成为一个痛苦。

避免的最佳解决方案是通过任何可用的后台任务框架。它们的优点是,它们将遵循生产者/消费者队列模式,并通过在后台运行的单独守护进程为您完成所有跟踪。但是这里的缺点是守护进程仍然是脆弱的。

另一个选择是集成队列或消息传递服务,如Rabbit MQ。这不仅可以扩展,而且可以在不同的语言中很好地实现。

在这种情况下我们所做的是:

  • 浏览器向组件A发送指令集
  • 组件A验证指令集
  • 组件A在新的"跟踪"ID下将指令集保存到DB STATUS=PENDING
  • 组件请求组件B完成工作
  • "Threading"在组件B中:
    • 组件B启动后台线程工作,后台线程做的第一件事是将"跟踪ID"的状态更新为STATUS=RUNNING
    • 组件B主线程返回组件A成功
  • 组件A从组件B获得"启动成功"消息,因此将自己的"启动成功"消息连同"跟踪ID"一起返回给浏览器。在此阶段,组件A完成了请求,所有组件A的资源都是空闲的。
  • 浏览器可以对组件A进行不同的调用来检查DB中"tracking ID"的状态
  • 同时,组件B的后台"线程"仍在工作,可能会根据"跟踪ID"记录进度
  • 组件B完成工作,更新DB、STATUS=OKSTATUS=ERROR中的"跟踪ID"状态,放弃所有资源。

从应用程序的角度来看,所有这些的优点是不需要等待工作完成。实际的工作是由"后台"线程完成的,就像您在shell中使用nohup dothework &启动它一样。关键是使用DB来监视"跟踪ID"的状态。