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

时间:2011-12-08 16:43:17

标签: c# java ajax multithreading jquery

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

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

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

关于如何处理这个问题的任何好主意?

2 个答案:

答案 0 :(得分:2)

通过生成线程,有多种方法可以手动处理这种情况。但是你将要面对的一个主要问题(我在编程经验中遇到过)是线程有点难以维护,如果处理不当会有一些缺点。首先,错误处理功能是有限的,您必须有一个外部表(持久化表)或全局变量记录或捕获所有这些错误。另一个问题是服务器可以采取的处理限制。如果你在后台产生了太多的线程,那么服务器处理限制以及它同时发出的数据库请求将会变得很麻烦。

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

另一个选择是集成排队或消息服务,如Rabbit MQ。这不仅可以扩展,而且可以用不同的语言实现非常好的实现。

答案 1 :(得分:1)

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

  • 浏览器将指令集发送到组件A
  • 组件A验证指令集
  • 组件A在新的“跟踪”ID STATUS=PENDING
  • 下将指令设置为DB
  • 组件向组件B发出请求以执行工作
  • “线程”在组件B中:
    • 组件B启动后台线程来完成工作,后台线程首先做的是将“跟踪ID”的状态更新为STATUS=RUNNING
    • 组件B主线程返回组件A
    • 成功
  • 组件A从组件B获得“已成功启动”消息,因此将其自己的“已成功启动”消息与“跟踪ID”一起返回给浏览器。在此阶段,组件A完成了请求,所有组件A资源都是免费的。
  • 浏览器可以对组件A进行不同的调用,以检查数据库中“跟踪ID”的状态
  • 同时,组件B的后台“线程”仍在进行工作,可能会记录“跟踪ID”的进度
  • 组件B完成工作,更新数据库中的“跟踪ID”状态,STATUS=OKSTATUS=ERROR并放弃所有资源。

所有这一切的优点是没有等待从您的应用程序的角度完成工作。实际的工作是由一个“后台”线程完成的,就像你在shell中用nohup dothework &踢掉它一样。关键是使用DB来监控“跟踪ID”的状态。