java - 为什么 Netty HTTP 处理程序不可共享?

标签 java garbage-collection netty instantiation java-11

Netty 实例化一组请求处理程序类 whenever a new connection is opened .这对于像 websocket 这样的东西来说似乎很好,在 websocket 的生命周期中连接将保持打开状态。

当使用 Netty 作为每秒可以接收数千个请求的 HTTP 服务器时,这似乎对垃圾收集产生了相当大的负担。每个请求都会实例化几个类(在我的例子中是 10 个处理程序类),然后在几毫秒后对它们进行垃圾回收。

在中等负载 ~1000 请求/秒的 HTTP 服务器中,这将是一万每秒实例化和垃圾收集。

看来我们可以简单地查看下面的答案创建可共享的处理程序,使用ChannelHandler.Sharable 消除这种巨大的GC 开销。它们只需要是线程安全的。

但是,我发现库中打包的所有非常基本的 HTTP 处理程序都不可共享,例如 HttpServerCodecHttpObjectAggregator。此外,没有一个 HTTP handler examples是可共享的。 99% 的示例代码和教程似乎都没有理会它。 Norman Maurer 的 book 中只有一个宣传语(Netty 作者)给出了使用共享处理程序的原因:

WHY SHARE A CHANNELHANDLER?

A common reason for installing a single ChannelHandler in multiple ChannelPipelines is to gather statistics across multiple Channels.

在任何地方都没有提及 GC 负载问题。


近十年来,Netty 一直在常规生产中使用。对于高度并发的非阻塞 IO,它可以说是现存最常用的 java 库。

换句话说,它的设计目的是为了做比我每秒 1000 次适中的请求更多的事情。

是否有我遗漏的东西使 GC 加载不是问题?

或者,我是否应该尝试实现自己的 Sharable 处理程序,使其具有类似的解码、编码和编写 HTTP 请求和响应的功能?

最佳答案

虽然我们一直致力于在 netty 中产生尽可能少的 GC,但在某些情况下这是不可能的。例如,http 编解码器等保持每个连接的状态,因此无法共享这些状态(即使它们是线程安全的)。

解决此问题的唯一方法是将它们合并,但我认为还有其他对象更可能导致 GC 问题,对于这些对象,我们会尽可能轻松地合并。

关于java - 为什么 Netty HTTP 处理程序不可共享?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58531825/

相关文章:

java - Swing 2D 游戏性能低下

ruby - 你有什么策略来保持低内存使用率?

haskell - 当 MVar 被垃圾回收时终止线程

java - 我应该使用 DefaultEventExecutorGroup 还是自定义 Java Executor?

c# - .NETTY : Second batch of data sent includes the first?

java - 如何将包含矩阵的文件读取为 vector 的 vector ?

java - org.hibernate.MappingException : Foreign key (FK12A711396456CA10:) must have same number of columns as the referenced primary key

java - 将 'markers' 放在 ImageIcon Java Swing 上的最佳方式?

unit-testing - Spring Framework - 单元测试设计

java - Netty 4在处理程序中多次读/写