views:

197

answers:

4

I have Java servlet-based web applications. I would like to implement some operations in asynchronous manner, like for example writing to a log.

I would like to avoid JMS overhead and do something simple.

Managing threads myself doesn’t seem such a good idea in a server environment, you would probably need to tap into server thread pool etc. What is the best alternative for simple asynchronous operation?

Edit:

Just for clarification, since many suggested using log4j or other logging library, writing to a log operation is here more of an example. I am interested how to perform asynchronously any operation that need not be performed sequentially. Idea is to reply to user immediately and to continue processing costly operation in another thread.

In regards to log issue, we have an audit log we implemented to write a lot of data to a database and is used by the user during audit operations and at Help Desk. Writing a lot of information to DB can be very costly. We do use log4j for system log and since the appender is file appender we have no performance issues with our system log.

A: 

If all you want to do is simple logging then Log4j is easy and simple to use.

ChadNC
Dont think log4j is async unless you use a JMS or custom appender :-)
Karl
http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/AsyncAppender.html
ChadNC
A: 

If you're just trying to write to a log in an async fashion I would avoid it completely and just use buffered output if appropriate.

I have never used it myself but the http://mina.apache.org/ project from apache has good reviews, however I think this is mostly at the network level.

Karl
A: 

You want to make heavier operations asynchronous, not very lightweight ones like logging. Once you form the log message, the actual writing of it should be very fast (after all, your disk controller does caching too).

So if you have a heavy operation that would bog down your web application and make it less responsive, it's generally a good idea to use a persistent message queue approach like JMS.

If you want to do logging, I'd suggest SLF4J, which is the successor to Log4J and very powerful and efficient.

If you're looking into logging on a multi-machine environment, one approach is to configure your logger to write messages to a multicast group, from which they are read and written to disk one or more log aggregation servers.

Jim Ferrans
+1  A: 

As many people said here, logging is not a good candidate for async. Nevertheless, I consider you have a good reason to belive otherwise.

In such a case, I'd use a Queue (e.g. ConcurrentLinkedQueue), and a low-priority thread (which you start at application startup and kill on shutdown, for instance, from a run-at-startup servlet). The thread should pick the messages from the Queue, and do it's deed. Thread should be woken up by a notify() method or in equal intervals.

Risk: Queue can grow uncontrollably under heavy load (as the thread may not get enough CPU cycles).

There are other ways to fire an async operation (e.g. Timer, Future, ...) but I don't think they are a good fit for fast small operations.

Vladimir Dyuzhev
Another reason would be to reduce the operation time visible by user by postponing the logging activity. In which case, again, you put log messages into Queue, return page to user, and then flush logging queue into the media (disk, DB, network logger). Total throughput is not higher, but user experience is better.
Vladimir Dyuzhev