代码之家  ›  专栏  ›  技术社区  ›  Thimmayya

如何将被重复调用的外部进程集成到Java WebApp中?

  •  3
  • Thimmayya  · 技术社区  · 16 年前

    我试图将非Java可执行文件集成到服务器端(Linux)上的Java WebAPP中。

    有关可执行文件的一些详细信息:
    用C++编写的。可执行文件从stdin或file获取一些输入并生成输出文件。可执行文件不是设计为长时间运行的过程,即它生成一个输出,然后消失。

    虽然为可执行文件启动单个进程相当便宜,但对它进行的调用数量可能很高。这可能导致生成过多的进程,从而降低服务器性能。

    如何在EXE中编写一些包装器或实用程序(Java),这样我就可以有效地运行

    1. 我的Java应用程序中的线程
    2. 长期运行的外部过程

    PS:我知道我可以使用Java中的运行时或PalueBuuditer来启动一个外部进程,并且可以使它多线程并使用一些队列,但是这并不能解决一次又一次地启动进程的问题。

    4 回复  |  直到 16 年前
        1
  •  1
  •   OscarRyz    16 年前

    如果你:

    a)可以修改源代码。

    我建议您创建一个长时间运行的进程,并将其公开为WebService。这样,进程将只在那里等待调用。

    b)有源代码/头,但不能修改。

    也许一个好主意是将它集成为库并用JNI或JNA从Java调用它,尽管这可能是非常痛苦的。

    c)没有源代码或无法修改。

    然后没有太多的选项,您必须创建一个线程队列,然后从那里限制进程的创建。

        2
  •  1
  •   Stephen C    16 年前

    如果启动C++应用程序花费的时间太长,那么几乎肯定的是,您将不得不编写一些C++代码来避免这种情况。

    一种选择是用合适的API将C++重构为库,并使用JNI或JNA从Java调用API。然而,JNI/JNA很难使用,并且有破坏JVM的倾向。当出现问题(例如,您的JVM崩溃)时,调试是困难的。

    一个更好的选择是重构C++应用程序作为守护进程。将“主”入口点替换为循环中执行以下操作的代码:

    while (true) {
        read request from a socket / pipe
        process request
        write answer to socket / pipe
    }
    

    如果使用管道,可以使用Java WebApp启动C++应用程序。 Runtime.exec(...) 然后通过管道流读写消息。如果使用(IPC或网络)套接字,您可以执行相同的操作,或者使C++应用程序多线程,以便它可以一次处理多个请求。

    您需要考虑的一个问题是多线程。您的Web容器(运行WebApp的东西)默认情况下可能是多线程的,因此您需要实现Java端来处理C++端的多线程或单线程特性。这可能是简单的,使得Java端对象被用来用同步方法来请求一个单独的对象。然而,这可能是性能瓶颈。

        3
  •  1
  •   Thorbjørn Ravn Andersen    16 年前

    JAVA中的节流可以使用合适的执行器来完成。在执行器中有很多容易获得的——我认为固定大小的线程池正是您所需要的。

    http://java.sun.com/javase/6/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool%28int%29

        4
  •  0
  •   Adam Goode    16 年前

    有多少过程“太多”?我建议在继续之前先衡量一下表现。在这种情况下,您可以无问题地启动和运行更多的进程,这比您预期的要多,尤其是因为程序的代码将在所有实例的内存中共享。