[英]Solution to the long running query problem in a web application (asynchronous request)
这是问题所在
企业Web应用程序的用户正在执行导致长(非常长)数据库查询(或其他长处理密集型任务)的任务
问题:
我想出了几个解决方案,但我不确定哪个更好(在所有方面,性能,最佳实践,优雅和可维护性),我想知道你推荐的解决方案是什么,如果有的话我错过了一个解决方案? (可能是的,很多)
糟糕的解决方案 :使用请求线程作为工作线程,在会话中保存进度状态,让AJAX调用检查另一个并行请求中的状态(在会话中)
折衷解决方案 :创建自己的线程池,处理监控线程,工作线程,并通过同步分配事务缓存或持久存储中的状态来处理集群。 这会释放请求,但创建应用程序服务器不知道的线程,并且不会在取消部署时关闭。 它取决于你以干净的方式关闭线程,并且总有可能你最终会漏掉一些东西。 这也不是J2EE的方法。
J2EE解决方案 :将JMS用于异步任务,这就是它的用途
Spring解决方案 :使用Spring批处理
你会在你的项目中做什么/做什么? 你知道其他什么解决方案? 您认为上面提到的哪一个是赢家?
我会把你所谓的“坏解决方案”和“j2ee解决方案”结合起来:
诀窍是匹配请求/响应对。 我会这样做:
NULL
作为值。 也将该id传递给UI。 NULL
就让UI线程使用先前生成的id轮询AMS。 这很干净,很好地从任何具体领域中抽象出来 。 纯粹的技术解决方案。
即使您不喜欢轮询,HTTP在设计上也是无状态的,我认为这种方式轮询只能在明确定义的时间间隔内进行。
无论如何,我实现了一个完全符合这种模式的系统,它运行得很好......
我之前使用的解决方案涉及Jetty Cometd而不是AJAX。 Ajax和Cometd之间的主要区别在于Cometd可以使用更多的pub / sub模型 - 客户端(在这种情况下是Web浏览器)加入发布者(您的应用程序),应用程序将更新和通知推送到Web浏览器适用于Web浏览器对服务器进行持续轮询的ajax模型。 即使您没有使用jetty,也可以使用Cometd解决方案 - 您可以将Jetty jar放入各自Web服务器的lib文件夹中,您应该很高兴。
向用户显示“您的请求已被接受且需要一小时才能获得更新”的消息
您创建一个存储所有这些事务的表,并在服务器上批量处理这些事务。
用户不必等待很长时间,他会很高兴看到这条消息。 处理完交易后,您可以发送确认电子邮件。
这是我认为最好的解决方案。
这些查询运行了多长时间?
如果您谈论的会话即将到期,也许最好让用户不要等待它。 对于用户来说,在该查询的选项卡中经常等待20分钟达到峰值总是很烦人。
因此,如果确实存在很长的查询,也许最好更改UI方法并让用户“订购”他(她)稍后回来查看的查询,或者甚至在邮件准备就绪时通过邮件通知。
在这种情况下,我将在DB中准备查询并在单独的表中缓存。 这意味着,我有一个Web服务器工作一次注册请求,有一个数据库任务或一个单独的进程/服务器根据请求准备查询并通知用户,然后让用户在用户返回时显示它们结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.