【问题标题】:Is it better to increase the number of worker threads or create my own thread pool in Netty?是增加工作线程的数量还是在Netty中创建自己的线程池更好?
【发布时间】:2019-07-16 01:05:05
【问题描述】:

假设我们的 Netty 服务器 (4.1.32) 响应 HTTP 调用。让我们进一步假设它必须执行某些阻塞操作才能响应传入请求,例如,它必须执行传出调用(此处使用不同的库)以加载外部数据。

Number of threads for NioEventLoopGroup with persistent connections 讨论

如果我的 messageReceived 方法阻塞或需要很长时间才能完成,会发生什么情况?

@Maksym 的回应

您应该避免在处理程序中使用线程阻塞操作。

很明显,只有有限数量的工作线程。因此,有效地阻塞所有可用的工作线程意味着 Netty 将排队任何进一步的请求,直到工作线程变得可用。

另一方面,按照建议将阻塞操作移动到我自己的线程上,将对线程切换产生性能影响,而可用硬件又会阻塞我自己的线程池。恕我直言,使用我自己的线程池只会增加另一层复杂性,但不会提高性能。相反,我宁愿增加工作线程的最大数量,让 Netty 完成对请求进行排队的工作。

这里建议的做法是什么?

【问题讨论】:

  • 理想情况下,您的应用程序中不应有任何阻塞代码。如果您想同时处理许多操作,从长远来看,庞大的线程池会给您带来很多性能问题,并且当您遇到一些理论限制时可能会发生灾难性故障。
  • @JohnnyV 有时会在需要读取数据库的应用程序中出现阻塞操作。您可以异步执行操作,但 IO 有时会阻塞

标签: java multithreading netty


【解决方案1】:

您应该使用自己的线程池,期间。 Netty 工作线程在许多连接之间共享,如果您阻止处理一个请求,则会损害其他请求。该设计假定您的代码快速返回,如果您需要阻止,则必须为此使用单独的线程。如果您需要执行非常昂贵的计算,则同样适用,在另一个线程中执行并返回。

如果您做过任何 Swing 编程,您可以将其与 GUI 线程进行比较。如果您阻止 GUI 线程,用户界面将挂起并变得无响应。不适合用户界面,也不适合高性能网络应用程序!

编辑:只是为了超级清楚,对于经典 IO,一个线程通常分配给一个请求,如果请求阻塞不是世界末日,如果线程池足够大,其他线程可以处理其他请求.使用 NIO,您不会为您的请求获得线程,您会被处理 IO 以处理事件的许多请求的线程调用,并且您应该尽快执行此操作,以便线程可以移动到另一个线程要求。阻塞对服务器来说真的很糟糕。

【讨论】:

  • 如果工作线程正在使用我自己的阻塞线程池(IO 到数据库)怎么办,这也会导致工作线程阻塞。我看不出你会在什么时候完全避免阻塞。它在工作线程或我自己的线程处阻塞。但是如果工作线程需要我自己的线程获取的数据库数据,它无论如何都会阻塞
  • 您的工作线程不能等待阻塞线程完成。 Netty 调用事件处理程序。他们应该很快回来,他们不需要在他们回来之前做所有的事情。如果您不能快速处理请求,请在不写响应的情况下返回。然后当阻塞线程完成并且你有你需要的东西时写响应。工作线程不必等待。
  • 我不明白你说“不写回复就返回”。从请求-响应的角度会发生什么。一个请求进来,我没有写响应就返回。当阻塞线程完成处理请求时,它将写入响应。处理请求的工作线程已经以空响应仪式完成。
  • 这样不行。在 Netty 中,请求和工作线程之间没有一对一的关系。您有一个可以读取和写入数据的通道。当有要阅读的内容时,您会被调用,因此您可以阅读请求。当您阅读完整的请求后,您可以处理它,但如果它是一个长时间运行的操作,您不需要使用调用您进行阅读的线程。您可以为阻塞操作分离一个单独的线程并返回。然后,当您有响应时,将其写入频道。不要担心原始线程。
猜你喜欢
  • 2014-09-27
  • 1970-01-01
  • 2011-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-02
  • 1970-01-01
相关资源
最近更新 更多