不确定为啥我的服务器在帧解码器中收到“channelInterestChanged”事件
Posted
技术标签:
【中文标题】不确定为啥我的服务器在帧解码器中收到“channelInterestChanged”事件【英文标题】:Not sure to understand why my server receives "channelInterestChanged" events in the frame decoder不确定为什么我的服务器在帧解码器中收到“channelInterestChanged”事件 【发布时间】:2012-03-14 20:05:01 【问题描述】:我实现了自己的帧解码器,以根据我们的协议解析通过 UDP 套接字(使用 NioDatagramChannelFactory 和 ConnectionlessBootstrap)接收到的字节。 为了在接收消息时跟踪服务器中发生的情况,我在解码器的每个回调方法中添加了跟踪日志。
似乎对于服务器收到的几乎每条消息,我们都可以看到在方法 channelInterestChanged() 中收到了两次事件“channelInterestChanged”。事件的值首先是 0 (OP_NONE),然后是 1 (OP_READ)。
我阅读了有关此的文档,但我仍然不确定为什么我会收到此类事件。我第一次通过它是因为接收缓冲区(或选择器队列)已满,但服务器接收此事件的次数与它接收“messageReceived”事件的次数相同(在调用 decode() 方法之前)和所有消息/frames 按预期正确解码。当消息丢失时,我根本看不到任何事件。在这种情况下,可能是因为数据报套接字的接收缓冲区已满。但是即使我增加了这个接收缓冲区,我仍然会看到这些事件并错过消息。
所以,我想知道为什么对于收到的每条消息,服务器还会收到两个“channelInterestChanged”,一个带有 OP_NONE 值,一个带有 OP_READ 值。请注意,在通道管道中,在我的帧解码器之后,有一个 ExecutionHandler 和另一个特定于业务的处理程序(它将 JMS 消息发送到 ActiveMQ 实例)。
对我有什么想法或解释吗?
谢谢。
【问题讨论】:
自己有兴趣知道。为什么不尝试附加 netty 源并对其进行调试,Netty 有一个fireEvent
方法,可以将这些事件上游/下游发送到通道中。也许它来自 java NIO 选择器 本身,而 Netty 只是将它传输到您的帧解码器。
【参考方案1】:
当从处理程序触发 DownStreamChannelStateEvent 时(例如调用 channel.setReadable()
、channel.setWriteable()
),该事件将更改 NioDatagramWorker
中频道的 nio 选择器键感兴趣的选项,稍后,将触发 UpstreamChannelStateEvent
并更改选项(即OP_READ
或OP_NONE
)
您的帧解码器处理程序收到UpstreamChannelStateEvents
,因为管道中的其他一些处理程序正在更改通道的读取兴趣选项(调用 channel.setReadable/setWriteable 的目的是限制读/写以避免拥塞,OutOfMemoryError
在应用程序中)。
如果您的管道中有任何MemoryAwareThreadPoolExecutor
(用于监控所用通道内存的大小),如果通道接收消息过快,它可能随时通过调用channel.setReadable()
来暂停或恢复读取。您可能必须使用最佳 maxChannelMemorySize、maxTotalMemorySize 配置 MATPE 实例,或者通过将其设置为 0 来禁用它。
【讨论】:
非常感谢这些非常清晰的解释!是的,我的管道中有一个 MATPE,是的,内存大小有一个特定的值。在我将这些参数设置为零后,我有效地注意到事件停止被触发。但直到现在我还不确定到底是为什么,它是如何在幕后工作的!以上是关于不确定为啥我的服务器在帧解码器中收到“channelInterestChanged”事件的主要内容,如果未能解决你的问题,请参考以下文章