Wolfgang,

please try using the SimpleHttpConnectionManager instead of MultiThreadedHttpConnectionManager.

Odi

Wolfgang Hoschek wrote:
I am planning on sending and receiving MANY (tens of tousands) small SOAP-like serial messages over the same persistent HTTP 1.1 connection, using a single client and thread (nothing fancy there). A High performance, low latency http library would be ideal.

HTTPClient performance seems devastating wrt. ab (apache benchmark): 4300 requests/sec vs. 20 requests/sec, i.e. two orders of magnitute difference, no matter what options I try with HTTPClient.

Source code to reproduce and full data is attached.
If anyone is interested, please let me know what I'm doing wrong, reproduce the effect and/or post working code that performs well in your experience.


ab -k -n 10000 http://localhost:8080/discofish/HelloWorldServlet > /tmp/out

Requests per second: 4313.48 [#/sec] (mean)

(For more data see full output in attachment)


[doggy /home/oliver/g5/users/hoschek] time disco-java.sh gov.lbl.dsd.discofish.client.HTTPBug 100 http://localhost:8080/discofish/HelloWorldServlet > /tmp/out2


real    0m4.876s
user    0m0.550s
sys     0m0.060s

--> Requests per second: 20.0

(For more data see full output in attachment)

Similar performance gap on static HTML pages (no need to use a servlet).

Environment: httpclient-2.0rc1, jdk-1.4.2, tomcat-4.1.27 (server.xml out of the box), 2GHz Pentium IV, Redhat 8.0.

Thanks,
Wolfgang.


------------------------------------------------------------------------


This is ApacheBench, Version 2.0.40-dev <$Revision: 1.116 $> apache-2.0
Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright (c) 1998-2002 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)


Server Software: Apache Server Hostname: localhost Server Port: 8080

Document Path:          /discofish/HelloWorldServlet
Document Length:        8 bytes

Concurrency Level:      1
Time taken for tests:   2.210253 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Keep-Alive requests:    9900
Total transferred:      1579500 bytes
HTML transferred:       80000 bytes
Requests per second:    4524.37 [#/sec] (mean)
Time per request:       0.221 [ms] (mean)
Time per request:       0.221 [ms] (mean, across all concurrent requests)
Transfer rate:          697.66 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:     0   11   7.6     11      37
Waiting:        0    0   0.5      0      17
Total:          0   11   7.6     11      37

Percentage of the requests served within a certain time (ms)
  50%     11
  66%     14
  75%     16
  80%     17
  90%     19
  95%     26
  98%     32
  99%     35
 100%     37 (longest request)


------------------------------------------------------------------------



...................................................................... ..............................goodbye


------------------------------------------------------------------------


package gov.lbl.dsd.discofish.client;

import java.io.IOException;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpRecoverableException;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.PostMethod;


public class HTTPBug { protected HttpClient client; protected String url; public static void main(String[] args) throws Exception { int k=0;

                int size = 1000;
                if (args.length > k) size = Integer.parseInt(args[k++]);
                
                //String url = "http://localhost:8080/discofish/HelloWorldServlet";;
                String url = "http://localhost:8080/discofish/index.html";;
                //String url = 
"http://itg.lbl.gov/~hoschek/discofish/disco-grep-usage.txt";;
                if (args.length > k) url = args[k++];
                
                MultiThreadedHttpConnectionManager connMgr = new 
MultiThreadedHttpConnectionManager();
                //connMgr.setMaxConnectionsPerHost(200);
                //connMgr.setMaxTotalConnections(200);
                HttpClient client = new HttpClient(connMgr);
                //HttpClient client = new HttpClient();
                
                for (int i=0; i<size; i++) {
                        PostMethod method = new PostMethod(url);
                        method.setRequestHeader("Content-type", "text/xml; 
charset=ISO-8859-1");
                        method.setRequestHeader("Accept", "application/soap+xml, 
application/dime, multipart/related, text/*");
                        method.setRequestHeader("SOAPAction", "");
                        
//method.setRequestContentLength(PostMethod.CONTENT_LENGTH_CHUNKED);                   
 
                        //method.setRequestBody(XMLUtil.msg2SoapString(new Receive(new 
TransactionID(), 1, 1, System.currentTimeMillis() + 10000, "single")));
                        method.setRequestBody("hello");
                        //method.setRequestContentLength(5);
                        int statusCode = -1;

                        /*Header[] headers;
                        headers = method.getRequestHeaders();
                        for (int j=0; j < headers.length; j++) {
                                System.out.print(headers[j].toString());
                        }

                        String requestBody = method.getRequestBodyAsString();
                        System.out.println(requestBody);
                        System.out.println();*/

                        
                        try {
                                // execute the method.
                                statusCode = client.executeMethod(method);
                        } catch (HttpRecoverableException e) {
                                System.out.println("A recoverable exception occurred, 
retrying.  " + e.getMessage());
                        } catch (IOException e) {
                                System.out.println("Failed to download file.");
                                e.printStackTrace();
                                System.exit(-1);
                        }
                        // Check that we didn't run out of retries.
                        if (statusCode == -1) {
                                System.out.println("Failed to recover from 
exception.");
                                System.exit(-2);
                        }
                        
                        //String responseBody = method.getResponseBodyAsString();

                        /*headers = method.getResponseHeaders();
                        for (int j=0; j < headers.length; j++) {
                                System.out.print(headers[j].toString());
                        }

                        System.out.println(responseBody);*/
                        if (i % 70 == 0) System.out.println();
                        System.out.print('.');

                        method.releaseConnection();
                        //method.recycle();
                }
                
                System.out.println("goodbye");
        }

}


------------------------------------------------------------------------


package gov.lbl.dsd.discofish.server;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloWorldServlet extends HttpServlet {

        public void doPost(HttpServletRequest request, HttpServletResponse response) 
throws IOException, ServletException {
                doGet(request, response);
        }
        
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws IOException, ServletException {
                
                response.setContentType("text/xml");

                ByteArrayOutputStream bytes = new ByteArrayOutputStream(1000);
                PrintWriter out = new PrintWriter(bytes, true);  // true forces 
flushing

out.println("</HTML>");

                // Set the content length to the size of the buffer
                response.setContentLength(bytes.size());

                // Send the buffer
                bytes.writeTo(response.getOutputStream());
                        
                /*out.flush();
                out.close();*/
                //response.flushBuffer();
        }

}



------------------------------------------------------------------------

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

-- _________________________________________________________________ NOSE applied intelligence ag

 ortwin glück                      [www]      http://www.nose.ch
 software engineer                 [email] [EMAIL PROTECTED]
 hardturmstrasse 171               [pgp key]          0x81CF3416
 8005 zurich                       [office]      +41-1-277 57 35
 switzerland                       [fax]         +41-1-277 57 12


--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to