ZappyAd
ZappyAd

Reputation: 21

Implementing asynchronous message queue in java

I have a java server that handles logins from multiple clients. The server creates a thread for each tcp/ip socket listener. Database access is handled by another thread that the server creates.

At the moment the number of clients I have attaching to the server is quite low (<100) so I have no real performance worries, but I am working out how I should handle more clients in the future. My concern is that with lots of clients my server and database threads will get bogged down by constant calls to their methods from the client threads.

Specifically in relation to the database: At the moment each client thread accesses the public database thread on its server parent and executes a data access method. What I think I should do is have some kind of message queue that a client thread can put its data request on and the database thread will do it when it gets round to it. If there is data to be returned from the data access call then it can put it on a queue for the client thread to pick up. All of this wouldn't hit the main server code or any other client threads.

I therefore think that I want to implement an asynchronous message queue that client threads can put a message on and the database thread will pick up from. Is that the right approach? Any thoughts and links to somewhere I can read up about implementation would be appreciated.

Upvotes: 2

Views: 5994

Answers (3)

Peter Lawrey
Peter Lawrey

Reputation: 533472

It sounds like what you want to do is limit the number of concurrent requests to the database you want to allow. (To stop it being overloaded)

I suggest you have a limited size connection pool. When too many threads want to use the database they will have to wait until a connection is free. A simple way to do this is with a BlockingQueue with all the connections created in advance.

private final BlockingQueue<Connection> connections = new ArrayBlockingQueue<Connection>(40); {
   // create connections
}

// to perform a query.
Connection conn = connections.get();
try {
    // do something
} finally {
    connections.add(conn);
}

This way you can keep your thread design much the same as it is and limit the number of concurrent queries to the database. With some tweaking you can create the connections as needed and provide a time out if a database connection cannot be obtained quickly.

Upvotes: 0

Nicholas
Nicholas

Reputation: 16056

What you are describing sounds like an ExecutorCompletionService. This is essentially an asynch task broker that accepts requests (Runnables or Callables) from one thread, returning a "handle" to the forthcoming result in the form of a Future. The request is then executed in a thread pool (which could be a single thread thread pool) and the result of the request is then delivered back to the calling thread through the Future.

In between the time that the request is submitted and response is supplied, your client thread will simply wait on the Future (with an optional timeout).

I would advise, however, that if you're expecting a big increase in the number of clients (and therefore client threads), you should evaluate some of the Java NIO Server frameworks out there. This will allow you to avoid allocating one thread per client, especially since you expect all these threads to spend some time waiting on DB requests. If this is the case, I would suggest looking at MINA or Netty.

Cheers.

//Nicholas

Upvotes: 3

duffymo
duffymo

Reputation: 308743

I would not recommend this approach.

JMS was born for this sort of thing. It'll be better than any implementation you'll write from scratch. I'd recommend using a Java EE app server that has JMS built in or something like ActiveMQ or RabbitMQ that you can add to a servlet engine like Tomcat.

I would strongly encourage you to investigate these before writing your own.

Upvotes: 5

Related Questions