Christopher Schultz wrote:
-----BEGIN PGP SIGNED MESSAGE-----
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!
D



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to