我有下面的代码将文件从一种格式格式化为另一种格式。处理需要一些时间,因此我们需要5分钟的等待时间,以防文件花费时间来处理我们将其销毁。
应用程序流程是从浏览器发出的http调用,它会打到spring boot @Controller
类,最后执行下面的代码,该代码属于springboot应用程序的@Service
类。
在负载测试中,即使关闭springboot应用程序后,我仍在任务管理器中看到许多formatter.exe
存在。我的问题是在多用户并发环境中实现的正确方法。也可以帮助我如何在同时发出多个请求时提高执行“ exe”的性能
process = Runtime.getRuntime().exec(runtime.exec("c:\\modifier\\formatter.exe"););
if (!process.waitFor(5, TimeUnit.MINUTES)) {
process.destroyForcibly();
process = null;
}
答案 0 :(得分:2)
这不是在5分钟内等待http
请求完成以及等待单独过程完成的好习惯。我假设您的端点是synchronized
(不是async
请求映射),因为您没有提供映射详细信息。
如果启动一个单独的进程,直到您明确关闭或终止它,该特定进程将在运行(如果该进程挂起)。请参阅this question,以了解如何终止进程,也请参阅this文档。
正如我所说,让http
请求等待5分钟并不是一个好习惯。当您使用Spring Boot时,我建议为该解决方案使用另一种方法。您只需使用asynchronous
批注使端点@Async
便可以不等待请求完成过程。 (在这种情况下,How To Do @Async in Spring是一个很好的文档)
现在,您可以将控制器实现更改为使用消息代理(RabbitMQ,ActiveMQ,JMS等)队列请求,并立即响应客户端(Messaging with RabbitMQ)。因此,即使没有启动进程,您的客户端(浏览器)也会立即看到响应。然后,您可以根据需要在客户端处理响应。
现在,您可以为来自代理的dequeue
消息编写一个不同的程序,并开始单独的过程。我们已经将响应发送给了客户端,该过程花费了多长时间都没有关系,并且在该过程完成之前,您无需销毁该过程(如果挂起,只需杀死该过程并re-queue
消息发送到队列。这样我们可以确保每个请求都会得到处理。
此过程完成后,您可以通过推送通知或 Websocket 实施并向其发送结果数据来通知客户端。
我知道这可能会简化一个简单的任务。但是,如果要保持功能的可靠性和可用性,这是值得做的。另外,您可以在Microservice体系结构中使用它。实际上,这是微服务的概念。这是一本不错的书,以了解有关this approach的知识。