【问题标题】:Implementing asynchronous message queue in java在java中实现异步消息队列
【发布时间】:2011-05-19 04:13:46
【问题描述】:

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

目前,我连接到服务器的客户端数量非常少(

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

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

【问题讨论】:

  • 不是答案,因此评论...您可能会想在“Java C10K 问题”上搜索 Google。基本上每个 TCP/IP 连接一个线程并没有像您所怀疑的那样切断它。您的问题不一定是您所写的“不断调用”,而是一旦客户端数量变高(如果您继续每个客户端使用一个线程),就会在大量线程之间不断交换。
  • 如今阻塞 IO 可以很好地执行高达 10K 的线程。尤其是 Java 6。这不像以前那么严重了。

标签: java multithreading messages


【解决方案1】:

听起来您想要做的是限制对您想要允许的数据库的并发请求数。 (防止它被超载)

我建议您使用有限大小的连接池。当太多线程想要使用数据库时,他们将不得不等待连接空闲。一个简单的方法是使用预先创建所有连接的 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);
}

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

【讨论】:

    【解决方案2】:

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

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

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

    干杯。

    //尼古拉斯

    【讨论】:

      【解决方案3】:

      我不推荐这种方法。

      JMS 就是为这种事情而生的。它比您从头开始编写的任何实现都要好。我建议使用内置 JMS 的 Java EE 应用程序服务器或 ActiveMQ 或 RabbitMQ 之类的东西,您可以将它们添加到 Tomcat 之类的 servlet 引擎中。

      我强烈建议您在编写自己的内容之前调查这些内容。

      【讨论】:

        猜你喜欢
        • 2010-12-11
        • 1970-01-01
        • 2013-04-12
        • 1970-01-01
        • 1970-01-01
        • 2011-10-18
        • 1970-01-01
        • 1970-01-01
        • 2023-03-24
        相关资源
        最近更新 更多