vert.x和BIO线程

时间:2014-03-14 18:26:35

标签: java multithreading akka vert.x

最近我开始学习reactiveevent-driven非阻塞Java框架,有一个引起我注意的问题 - vert.x

我想同样的问题可能适用于 akka(Play框架),因为他们的理念或其中一个目标是相同的 - 这就是减少线程数,从而提高可扩展性一个应用程序

vert.x表明它消耗的线程数相当于CPU内核的数量,但同时也要记住,有时你必须进行阻塞操作,因此它鼓励开发人员执行阻塞操作一个单独的工作线程(工人垂直方面的vert.x)。

这就是我们提出问题的地方:

  • 如果我应该在一个新的单独的上执行阻塞IO操作 线程,这意味着每个执行阻塞操作的用户都有 一个新的线程,因此线程数再次变得相等 经典阻塞线程模型中的用户数量?

一个真实的例子是JDBC查询 - 如果1000个并发用户通过JDBC查询SQL数据库,则每个用户都会为该阻塞操作生成自己的工作线程。从我的观点来看,与传统的阻塞线程模型相比,没有线程保留,改进的可伸缩性或RAM备用。我一定错过了什么......或者不是?提前感谢所有答案。

4 个答案:

答案 0 :(得分:2)

生成1000个并发线程查询SQL数据库是没有意义的 - 仅仅因为典型的数据库不能承受如此多的同时连接,典型的数字是10-15。解决方案是组织一个特殊的线程池,每个线程都有一个开放的连接,并提供访问数据库的任务。任务被提交到公共阻塞队列,并且工作线程在循环中从该队列读取。任务是

的实例
interface DBRunnable {
  public void run(Connection conn);
}

工作线程将其连接传递给任务:

public void run() {
  Connection conn = DriverManager.getConnection(...);
  while (true) {
     DBRunnable task=queue.take();
     task.run(conn);
  }
}

答案 1 :(得分:0)

vert.x建议在计算机上运行线程而不是用户方面。

他们所说的是,如果你有16个可用的CPU内核并且有16个就绪线程,那么如果你对其中一个执行阻塞操作,那么只有15个线程最多可以工作,因此只有15个你的CPU核心实际上正在工作。你的1个内核正在等待!

因此,为防止拥有一个空闲内核,他们建议您再创建一个线程并为其提供阻塞任务,这样您仍然可以在16个CPU内核上运行16个线程。

阻塞线程的数量并不重要(只要它不是太大......),因为它们实际上并没有消耗太多的CPU能力。

它与通常的阻止模型不同,因为您隔离了不需要太多资源的阻止操作。剩下的就是在你拥有的工作线程中共享剩余的事件驱动操作。

答案 2 :(得分:0)

如前所述,您应该使用连接池,但是如果您对数据库访问感兴趣而不是专门的JDBC,则可以查看异步数据库驱动程序,例如:

这些驱动程序依赖于netty,因此它的所有IO操作都是非阻塞的,这意味着您不需要拥有工作线程池。线程越少意味着操作系统级别的上下文切换越少,从而带来更好的性能。

可悲的是,这些驱动程序并不多(我只知道MySQL和PostgreSQL)所以如果你被迫与其他RDBMS合作,你可能会运气不好。

答案 3 :(得分:0)

正如其他人所建议的那样,请查看mysql和postgres的异步驱动程序,这两个驱动程序都有专门为vert.x制作的客户端。这两个数据库涵盖了RDMS的大多数用例。

另一个非阻塞选项是MongoDB,它有一个定制的非阻塞vert.x客户端。效果很好,但不是SQL。

相关问题