2010-12-02 275 views
1

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

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

具体来说就数据库而言:目前每个客户端线程都访问其服务器父级上的公共数据库线程并执行数据访问方法。我认为我应该做的是拥有某种客户端线程可以将其数据请求放入其中的消息队列,并且数据库线程在接收到数据时将执行该消息队列。如果有数据要从数据访问调用中返回,那么它可以将它放在队列中供客户端线程使用。所有这些都不会触及主服务器代码或任何其他客户端线程。

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

+0

不是一个答案,因此评论...你可能会想要Google上的“Java C10K问题”。基本上每个TCP/IP连接一个线程不会因为您怀疑而削减它。你写的问题不一定是*“constant calls”*,但是一旦客户端数量变高(如果每个客户端使用一个线程),就会在巨大数量的线程之间不停地交换数据。 – SyntaxT3rr0r 2010-12-02 14:43:16

回答

4

我不会推荐这种方法。

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

我强烈建议您在编写自己的作品之前调查一下。

1

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

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

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

干杯。

//尼古拉斯

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

这样你就可以保持你的线程设计大同小异,并且限制并发查询到数据库的数量。通过一些调整,您可以根据需要创建连接,并在无法快速获取数据库连接时提供超时。