1

Jetty Web サーバーを実行しており、それを使用して、GET 経由で受け取るパラメーターに応じていくつかの bash スクリプトを実行しています。私は Jetty を使ったことがないので、ここからいくつかのものをつなぎ合わせて動作させました。私の問題は、リクエストがない場合は最大 100 MB の RAM でアイドル状態になり、約 12 時間後には最大 1 GB の RAM でアイドル状態になることです。これは、要求が正当である場合に bash スクリプトを実行するだけのものにとっては、非常に多くのことのように思えます。サーブレットが最終的に提供する平均ファイル サイズは約 400 KB です。

サーバーの始動方法:

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

次の行のようになります。

scriptOutput += line + '\n';

大量のメモリを消費しています。取得した情報を応答で書き戻さないのはなぜですか?

于 2012-07-28T20:39:45.043 に答える
0

Reimeus が言ったように、出力を取得したらエコーする必要があります。その場合は、プロセス出力を送信する前に、応答ヘッダー (コンテンツ タイプ、ステータス コード) を送信する必要があります。

少なくとも、Strings を連結する代わりに StringBuilder を使用する必要があります。

于 2012-09-04T16:07:57.720 に答える