tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Kerber <>
Subject Re: Performance with many small requests
Date Mon, 11 May 2009 23:48:30 GMT
Christopher Schultz wrote:
> Hash: SHA1
> Peter,
> On 5/8/2009 7:26 AM, Peter Crowther wrote:
>> Decrypt: parallel.
>> Send ack: parallel.
>> Increment counters: synced.
>> Write to log file: synced (or you'll have some very odd stuff happening).
> I'd go further and suggest that you re-factor your design so that your
> servlet is very simple. Something like this:
> public void doPost(HttpServletRequest request,
>                    HttpServletResponse response)
>   throws IOException, ServletException
> {
>    RequestCounter counter = ...; // get from app scope? Class-level?
>    RequestLogger logger = ...; // same here
>    RequestProcessor processor = ...; // same here
>    counter.count();
>    processor.processRequest(request, response, false);
>    logger.log(request, response);
> }
> Then its up to the RequestCounter to maintain its own synchonization (if
> necessary) instead of your servlet having to know the semantics of
> thread-safety, etc. Same with the logger. As someone mentioned, most
> logging frameworks handle synchronization for you, and most of them can
> buffer the output to their log files so that you are getting the best
> performance you can.
> I highly recommend using a logging framework, or developing something
> that meets your needs that is self-contained, can accept log entries
> from multiple concurrent clients (your servlets), and buffers output to
> the log file to keep performance up.
I've been meaning to look into some more sophisticated logging 
techniques, and this exercise has given me some good incentive to do so 
sooner rather than later.  However, it doesn't look at the moment like 
disk writes are a limiting factor in this app's performance.  My latest 
thread dump indicates that the socket read is where most of the waits 
are at.  Because the requests are so small, I imagine that network 
latency is a far bigger factor than gross throughput is.

I definitely should hook a profiler to the app so I can be sure of 
what's taking the time, though.

> What is it that processRequest actually does? Decryption? Hmm... is it
> possible for you to save the decryption for later? You could have a
> service that simply logs the notifications and then have a batch job
> that later does the decryption and throws-out all the
> incorrectly-encrypted data. Just another option.
Basically the entire job of this application (servlet) is to accept the 
POSTs from the clients in the field, decrypt them, do a few sanity 
checks on the raw data, and dump them into a file on disk (we call it a 
"cache" file).  There are separate apps that then continuously read the 
data from the cache file and do all kinds of processing on it, stuff it 
into a database, and check various values and trends for near-realtime 
alerting purposes.  Moving the decryption to a later step in the process 
would be possible, but would require rewriting another application, for 
probably very little net gain.

Early on in the design, we considered doing it all in one application, 
but felt that this method gave us a little more overall reliability, 
because one piece could go down without affecting the others, and then 
it could catch up when it came back up.  It also allowed us to profile 
each section separately, making it a little easier to find the bottlenecks.

> Finally... if you are logging all requests, is it necessary to keep a
> daily and total request count? You can avoid the synchronization of
> those counters entirely by ... not bothering to count them. Again,
> retrospective counting is a possibility.
The counting isn't a core requirement of the application; I just put it 
in a a way to help me monitor its progress during the day, to be sure it 
hasn't locked up or lost a network connection somewhere along the way.  
Incrementing a counter can't be much of a synchronization bottleneck, 
and if I switch to an AtomicInteger, it should be even less of one.

Thanks for the comments!

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message