Our development team are creating a new routing system for instant messaging, all on JBoss 3.2.2.
The expected volumes are quite high, but during short periods (5-30 minutes tvice a day) we can expect an extremly high volume.
One of the requirements is that we can deliver the messages from point A to point B,C,D... very fast without delays during the peaks.
Point A is a remote application acting as a receiver of messages, pushing the messages onto a JMS-queue to achive an asynchronous behavior.
Point B, C and D are different URLs expecting HTTP-requests.
We are running a prototype today using message driven beans as consumers. The MDB makes the request over a short lived socket connection (fast response time).
Now to our potential problems (discussions and recommendations are highly appriciated):
To be able to route the message correctly we have a quite expensiv data look-up process to do, involving many entity beans and relationships between them.
The data are highly static so one solution would be to cache the result from the look-up, using 'read only' and 'commit option A' on involved entity beans.
How fast and efficient is this container cache? Are we better of implementing our own cache functionality in a session bean, just storing the data object in a map?
Next problem is a bit more complex and have to do with the logging of data produced for each message.
We would like an asynchronous logging to be put in place, i.e asyncronous insertions into our database.
The reason for this is the fact that the database insertions comes with a cost and we don't want to see this as a bottleneck during the message peak mentioned earlier.
One solution could be to push the data to be logged on to another JMS-queue and let MDBs do the logging in their own speed in the background. What cost will this approach have? The queue is persistent, i.e producing insertions into the Jboss db. We do believe that this cost would be smaller than a synchronous logging into many tables. right/wrong?
Is there another way of asynchronous logging. Can we have newly created entity beans to wait and save the data in the backround in an asynchronous fashion without the JMS-queue?
Ok a power-cut would mean lost data (something that the j2ee-spec addresses quite well). But what if we feel that we could live with a potential data-loss under exreme circumstances (we can always use power-backup that could keep the hardware going).
Can we in one way or another just store the log-data in memory and have a background process to do the insertions, or is this violating the whole idea behind J2EE?
Thanks for your time
> How fast and efficient is this container cache?
It's basically a map lookup where using primary key to map to instance with bean's state.
> Are we better of implementing our own cache functionality
> in a session bean, just storing the data object in a
Impossible to say, depends on your application profile whether you'd be able to build a second level cache that improves performance (it might be possible if you're able to take advantage of specific profile your application usage has that a more generic cache is not aware of -- or it might not).
> One solution could be to push the data to be logged
> on to another JMS-queue and let MDBs do the logging
> in their own speed in the background. What cost will
> this approach have? The queue is persistent, i.e
> producing insertions into the Jboss db. We do believe
> that this cost would be smaller than a synchronous
> logging into many tables. right/wrong?
Asynchronous will be faster from your application point of view. For the best performance you will need to relax some requirements for the persistence of the logging information, accepting that in case of failure some log messages may be lost.
> Is there another way of asynchronous logging. Can we
> have newly created entity beans to wait and save the
> data in the backround in an asynchronous fashion
> without the JMS-queue?
Log4j allows asynchronous logging, you could write a logger (or use their existing ones if applicable) to make sure your entity inserts are not part of the processing performance. Again, you need to decide what type of loss of log information is acceptable in case of a failure to determine what performance you're able to get out of the system.
How fast and efficient is this container cache? Are
we better of implementing our own cache functionality
in a session bean, just storing the data object in a
First, make sure the container cache is your bottleneck. If you are relying on a database query to load primary keys, then you will run much slower than with your own Map. Make sure the only finder you need to use is findByPrimaryKey.
Also, strip away unused interceptors from your CMP container in the standardjboss.xml file.
All that being said, I find navigating a few hundred cached entities to be very fast. Once I get into a few thousand, I see noticeable performance differences between using the CMP container and using a cache.
> Make sure the only finder you need
> to use is findByPrimaryKey.
Is the findByPrimaryKey() the only finder that takes advantage of the caching mechanism?
I have several complex finders, and was hoping that the cache would be used for all my lookups.
For complex finders, JBoss will always execute the query to determine the primary keys of the entities that match the criteria. You can verify this by turning on CMP logging.
Once JBoss has obtained the primary keys, the entities themselves will be loaded from cache.
To my knowledge, there is no way to ask JBoss to cache the query results, and such caching would yield unreliable results unless your back-end were entirely read-only.