在java中实现异步消息队列

时间:2010-12-02 14:32:31

标签: java multithreading messages

我有一个java服务器来处理来自多个客户端的登录。服务器为每个tcp / ip套接字侦听器创建一个线程。数据库访问由服务器创建的另一个线程处理。

目前我连接到服务器的客户端数量非常少(<100),所以我没有真正的性能担忧,但我正在研究如何在未来处理更多客户端。我担心的是,对于很多客户端,我的服务器和数据库线程会因客户端线程对其方法的不断调用而陷入困境。

特别是与数据库有关:当前每个客户端线程访问其服务器父级上的公共数据库线程并执行数据访问方法。我认为我应该做的是拥有某种消息队列,客户端线程可以将其数据请求置于其上,并且数据库线程将在它到达它时执行它。如果有数据要从数据访问调用返回,那么它可以将其放在队列中以供客户端线程获取。所有这些都不会命中主服务器代码或任何其他客户端线程。

因此,我认为我想实现一个异步消息队列,客户端线程可以在其上发送消息并且数据库线程将从中获取。这是正确的方法吗?任何关于我可以阅读有关实施的地方的想法和链接都将不胜感激。

3 个答案:

答案 0 :(得分:5)

我不推荐这种方法。

JMS就是为了这种事而出生的。它会比你从头开始编写的任何实现都好。我建议使用内置了JMS的Java EE应用服务器或者像ActiveMQ或RabbitMQ那样可以添加到Tomcat等servlet引擎的Java EE应用服务器。

我强烈建议您在编写自己之前对其进行调查。

答案 1 :(得分:1)

您所描述的内容听起来像ExecutorCompletionService。这本质上是一个异步任务代理,它接受来自一个线程的请求(RunnableCallable s),以Future的形式返回即将到来的结果的“句柄”。然后,请求在thread pool(可能是single thread thread pool)中执行,然后请求的结果通过Future传递回调用线程。

在提交请求和提供响应之间,您的客户端线程将只等待Future(具有可选的超时)。

但是,我建议,如果您期望客户端数量(以及客户端线程)大幅增加,那么您应该评估一些Java NIO Server框架。这将允许您避免为每个客户端分配一个线程,特别是因为您希望所有这些线程花费一些时间等待数据库请求。如果是这种情况,我建议您查看MINANetty

干杯。

//尼古拉斯

答案 2 :(得分:0)

听起来你想要做的是限制你想要允许的数据库的并发请求数。 (为了阻止它过载)

我建议您使用有限大小的连接池。当太多线程想要使用数据库时,他们必须等到连接空闲。一个简单的方法是使用BlockingQueue预先创建所有连接。

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);
}

通过这种方式,您可以使线程设计保持原样,并限制对数据库的并发查询数。通过一些调整,您可以根据需要创建连接,并在无法快速获取数据库连接时提供超时。

相关问题