1

我正在运行一个 Jetty Web 服务器并使用它来执行一些 bash 脚本,具体取决于它通过 GET 接收到的参数。我从未与 Jetty 合作过,所以我从这里拼凑了一些东西来让它工作。我的问题是,当没有请求时,它会在大约 100mb 的内存处闲置,大约 12 小时后,它会闲置高达 1gb 的内存。如果请求是合法的,这对于只运行 bash 脚本的东西来说似乎是一个可怕的事情。servlet 最终提供的平均文件大小约为 400kb。

服务器如何启动:

public void startServer() {

    String hostname = "localhost";
    int port        = 7500;

    Server server = new Server();

    Connector connector = new SelectChannelConnector();
    connector.setHost(hostname);
    connector.setPort(port);

    server.setConnectors(new Connector[]{connector});
    server.setStopAtShutdown(true);

    ServletContextHandler context = new ServletContextHandler();
    context.setContextPath("/");
    context.addServlet(new ServletHolder(new DaemonServlet()), "/call/*");

    HandlerList handlers = new HandlerList();
    handlers.setHandlers(new Handler[] { context });

    server.setHandler(handlers);
    server.start();
    server.join();
}

小服务程序(DaemonServlet):

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {

    String msg = "";

    String call = request.getParameter("call");
    ProcessBuilder pb = null;
    Process p = null;

    switch (call) {
    case "sendAction": // Sends an action to a process with a certain ID
        pb = new ProcessBuilder("/bin/bash", "/opt/test/process.sh", request.getParameter("process"), request.getParameter("action"));
        break;
    case "getFile": // Reads the file with the given ID into a string, to be returned by Jetty
        pb = new ProcessBuilder("/bin/bash", "/opt/test/getFile.sh", request.getParameter("fileId"));
        try {
            p = pb.start();
            BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String scriptOutput = "";
            String line;
            while ((line = br.readLine()) != null) {
                scriptOutput += line + '\n';
            }
            br.close();
            msg = scriptOutput;
            p.destroy();
            p = null;
        } catch (Exception e) {}
        break;
    }

    response.setContentType("text/html");
    response.setStatus(HttpServletResponse.SC_OK);
    response.getWriter().println(msg);
}

这里有什么似乎设置不正确的地方吗?

4

2 回答 2

0

正如 Reimeus 所说,您可能应该在得到输出时回显它。如果采用这种方式,则应在发送流程输出之前发送响应标头(内容类型、状态代码)。

至少,您应该使用 StringBuilder 而不是连接 Strings

于 2012-09-04T16:07:57.720 回答
0

它看起来像这条线:

scriptOutput += line + '\n';

正在消耗大量内存。为什么不通过响应写回信息呢?

于 2012-07-28T20:39:45.043 回答