0

初め、

解決策を見つけるために多くのことを検索しましたが、適切な解決策を見つけることができませんでした。

環境

  • (生産的) Mongoose WebServer は単純な GET 要求に応答します (すべてのデータは QueryString を介して送信されます)
  • Apache HttpClient (単一インスタンス!) は、数十万の単一リクエストを順番に作成するために使用されます。
  • マングースと対話するApache HttpClientは非常にうまく機能します

    // after each request
    getMethod.releaseConnection();
    ...
    

問題

  • (モック) Sun HttpServer を使用した WebServer の実装は、FireFox / Curl で正常に動作します
  • 本番サーバーに対して実行する場合と同様に Apache HttpClient を使用すると、クライアントでのパフォーマンスがひどい (~ 1 リクエスト/秒)
  • ネットで見つかった次のコードで Apache HttpClient を使用すると、
    • クライアントでの大幅なパフォーマンスの向上
    • 処理された要求と同じ数の CLOSE_WAIT 状態のオープン ソケットによるリソースの浪費 (使用可能な FD がなくなるまで!)

コード:

HttpConnectionManager mgr = httpClient.getHttpConnectionManager();
    if (mgr instanceof SimpleHttpConnectionManager) {
    ((SimpleHttpConnectionManager)mgr).shutdown();
}

明らかに、http サーバーの実装に何かが欠けているため、この極端な「遅さ」が発生します。

ヒント/ヘルプをいただければ幸いです。

前もって感謝します!


コード

HttpServer

public static void main(String[] args) throws Exception {
        //System.setProperty("sun.net.httpserver.maxIdleConnections", "10");
        //System.setProperty("sun.net.httpserver.idleInterval", "2000");

        HttpServer server = HttpServer.create();

        server.bind(new InetSocketAddress("localhost", 11111), -1);
        InetSocketAddress addr = server.getAddress();
        HttpContext contextSearch = server.createContext("/search.to",
                new TrufflesSearchHandler());

        contextSearch.getFilters().add(new ParameterFilter());
        server.setExecutor(null); // creates a default executor
        server.start();
    }

HttpHandler

    static class SearchHandler implements HttpHandler {
        private JSONParser jsonParser = new JSONParser();

        public void handle(HttpExchange exchange) throws IOException {
            Map<String, Object> params = (Map<String, Object>) exchange
                    .getAttribute("parameters");
            String expectedResponse = "";
            int expectedHitPlace = -1;

            try {
                expectedResponse = (String) params.get("expectedResponse");
                expectedHitPlace = Integer.parseInt((String) params
                        .get("expectedHitPlace"));
            } catch (Exception e) {
                e.printStackTrace();
            }

            JSONArray resultArray = null;
            try {
                resultArray = (JSONArray) jsonParser.parse(new String(Base64
                        .decodeBase64(expectedResponse)));
                fillResponseWithDummyData(resultArray, expectedHitPlace);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            String response = "{ \"results\": " + resultArray + "}";

            Headers headers = exchange.getResponseHeaders();
            headers.add("Connection", "keep-alive");
            headers.add("Content-Type", "text/plain");
            headers.add("Content-length", "" + response.getBytes().length);
            // headers.add("Keep-Alive", "timeout=5 max=10");
            exchange.sendResponseHeaders(200, 0);
            // exchange.sendResponseHeaders(200, response.getBytes().length);
            OutputStream os = exchange.getResponseBody();
            os.write(response.getBytes());
            os.flush();
            os.close();
            // exchange.close();
        }

ParameterFilter

@SuppressWarnings("restriction")
public class ParameterFilter extends Filter {

    @Override
    public String description() {
        return "Parses the requested URI for parameters";
    }

    @Override
    public void doFilter(HttpExchange exchange, Chain chain)
        throws IOException {
        parseGetParameters(exchange);
        parsePostParameters(exchange);
        chain.doFilter(exchange);
    }    

    private void parseGetParameters(HttpExchange exchange)
        throws UnsupportedEncodingException {

        Map<String, Object> parameters = new HashMap<String, Object>();
        URI requestedUri = exchange.getRequestURI();
        String query = requestedUri.getRawQuery();
        parseQuery(query, parameters);
        exchange.setAttribute("parameters", parameters);
    }

    private void parsePostParameters(HttpExchange exchange)
        throws IOException {

        if ("post".equalsIgnoreCase(exchange.getRequestMethod())) {
            @SuppressWarnings("unchecked")
            Map<String, Object> parameters =
                (Map<String, Object>)exchange.getAttribute("parameters");
            InputStreamReader isr =
                new InputStreamReader(exchange.getRequestBody(),"utf-8");
            BufferedReader br = new BufferedReader(isr);
            String query = br.readLine();
            parseQuery(query, parameters);
        }
    }

     private void parseQuery(String query, Map<String, Object> parameters)
         throws UnsupportedEncodingException {
         String encoding = System.getProperty("file.encoding");
         if (query != null) {
             String pairs[] = query.split("[&]");

             for (String pair : pairs) {
                 String param[] = pair.split("[=]");

                 String key = null;
                 String value = null;
                 if (param.length > 0) {
                     key = URLDecoder.decode(param[0],
                         encoding);
                 }

                 if (param.length > 1) {
                     value = URLDecoder.decode(param[1],
                         encoding);
                 }

                 if (parameters.containsKey(key)) {
                     Object obj = parameters.get(key);
                     if(obj instanceof List<?>) {
                         List<String> values = (List<String>)obj;
                         values.add(value);
                     } else if(obj instanceof String) {
                         List<String> values = new ArrayList<String>();
                         values.add((String)obj);
                         values.add(value);
                         parameters.put(key, values);
                     }
                 } else {
                     parameters.put(key, value);
                 }
             }
         }
    }

}
4

0 に答える 0