【问题标题】:SpringBoot Process Runtime Performance issueSpringBoot 进程运行时性能问题
【发布时间】:2023-03-10 09:12:02
【问题描述】:

我有下面的代码将文件从一种形式格式化为另一种形式。处理需要一些时间,所以我们有 5 分钟的等待时间,以防文件需要时间来处理我们销毁它。

应用程序流程是一个 http 调用,来自浏览器,它点击 spring boot @Controller 类,最后执行下面的代码,该代码进入 springboot 应用程序的 @Service 类。

在负载测试中,我在任务管理器中看到许多 formatter.exe 存在,即使在 springboot 应用程序关闭后也是如此。我的问题是在多用户并发环境中实现的正确方法。当同时发出多个请求时,也可以帮助我如何提高执行“exe”的性能

process = Runtime.getRuntime().exec(runtime.exec("c:\\modifier\\formatter.exe"););

if (!process.waitFor(5, TimeUnit.MINUTES)) {
  process.destroyForcibly();
  process = null;
}

【问题讨论】:

    标签: java spring-boot concurrency


    【解决方案1】:

    等待http 请求在 5 分钟内完成以及等待单独的进程完成不是一个好习惯。我假设您的端点是synchronized(不是async 请求映射),因为您没有提供映射详细信息。

    如果您启动一个单独的进程,直到您明确关闭或终止它,该进程将运行(如果该进程挂起)。请参考this question 以了解如何终止进程并参考this 文档。

    正如我所说,让http 请求等待 5 分钟并不是一个好习惯。当您使用 Spring Boot 时,我建议对此解决方案采用不同的方法。您可以简单地使用 @Async 注释使您的端点 asynchronous 不等待请求直到过程完成。 (How To Do @Async in Spring 在这种情况下是一个很好的文档)

    现在您可以更改控制器实现以使用消息代理(RabbitMQ、ActiveMQ、JMS 等)队列请求并立即响应客户端 (Messaging with RabbitMQ)。因此,即使没有启动进程,您的客户端(浏览器)也会立即看到响应。然后,您可以根据需要在客户端处理响应。

    现在您可以为来自代理的dequeue 消息编写不同的程序并启动单独的进程。该过程需要多长时间并不重要,因为我们已经向客户端提供了响应,并且您不需要在该过程完成之前销毁该过程(如果它挂起,只需终止该过程并 re-queue 消息队列。这样我们可以确保每个请求都会被处理)。

    处理完成后,您可以通过推送通知或 Websocket 实现向客户端通知结果数据。

    我知道这可能会过度执行一项简单的任务。但是如果你想保持你的功能的可靠性和可用性,这是值得的。此外,您可以在微服务架构中使用它。事实上,这是一个微服务的概念。这是了解this approach 的好书。

    【讨论】:

    • Sachith,一个问题,当我们使用 t.schedule(killer, 30000); 时,您提供的链接堆栈链接是否真的需要使用“p.waitFor()”。我认为日程安排会很小心,p.waitFor() 似乎是多余的stackoverflow.com/questions/14483397/…
    • 是的,p.waitFor() 函数将使您的应用程序的工作线程等待外部进程在外部终止。这意味着,它可以让您的工作线程无限期地暂停,直到您使用外部进程完成工作。如果外部进程在进程完成后自行终止,这将是使用的正确功能,而不是在修复时间后杀死它,因为每个进程的处理时间可能会有所不同。但在您的情况下,如果您的进程在某个时候不会自行终止,最好使用t.schedule(killer, 30000)
    猜你喜欢
    • 2012-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多