Netty 网状管道警报

Netty 网状管道警报,netty,Netty,Netty 4发出警告“丢弃1条到达管道末端的入站消息。请检查管道配置”。这是什么意思?应该如何处理? (之前根据公认的答案解决,但我更希望得到关于其含义和管道如何工作的一般解释) 为了最大化净反馈,客户端管道设置如下: pipeline.addLast("logger", new LoggingHandler(LogLevel.TRACE)) pipeline.addLast("HttpRequestEncoder", new HttpClientCodec) pipeline.addLast

Netty 4发出警告“丢弃1条到达管道末端的入站消息。请检查管道配置”。这是什么意思?应该如何处理? (之前根据公认的答案解决,但我更希望得到关于其含义和管道如何工作的一般解释)

为了最大化净反馈,客户端管道设置如下:

pipeline.addLast("logger", new LoggingHandler(LogLevel.TRACE))
pipeline.addLast("HttpRequestEncoder", new HttpClientCodec)
pipeline.addLast("handler", new myHandler)
当Netty发送两条http消息并由服务器端成功接收和确认时,我在客户端通过Netty登录的所有信息是:

12 [main] DEBUG io.netty.util.internal.InternalLoggerFactory  - Using Log4J as the default logging framework
164 [nioEventLoopGroup-1-2] DEBUG io.netty.channel.nio.SelectorUtil  - Using select timeout of 500
164 [nioEventLoopGroup-1-2] DEBUG io.netty.channel.nio.SelectorUtil  - Epoll-bug workaround enabled = false
229 [nioEventLoopGroup-1-2] WARN io.netty.channel.DefaultChannelPipeline  - Discarded 1 inbound message(s) that reached at the end of the pipeline. Please check your pipeline configuration.
230 [nioEventLoopGroup-1-2] WARN io.netty.channel.DefaultChannelPipeline  - Discarded 1 inbound message(s) that reached at the end of the pipeline. Please check your pipeline configuration.
而日志记录的设置最低限度为:

BasicConfigurator.configure       
InternalLoggerFactory.setDefaultFactory(new Log4JLoggerFactory)

这意味着消息到达了管道的末尾,没有“入站处理程序”能够处理它。大多数情况下,这表明ChannelPipeline中存在“配置”错误。

在Netty 4中,服务器或客户端中使用的HTTP解码器始终会为单个HTTP消息生成多个消息对象:

1       * HttpRequest / HttpResponse
0 - n   * HttpContent
1       * LastHttpContent
换言之:

  • 服务器接收1个HttpRequest、0-n个HttpContent和1个HttpLastContent
  • 客户端接收1个HttpResponse、0-n个HttpContent和1个HttpLastContent
因此,如果处理程序只使用HttpRequest/HttpResponse,那么其他消息将到达管道的末尾。您需要使用它们,这就是您的管道“配置错误”的地方

o您可以将HttpObjectAggregator添加到管道中,以便生成FullHttpRequest/FullHttpResponse消息:

pipeline.addLast( "http-aggregator", new HttpObjectAggregator( MAX_SIZE ) );

但这意味着整个请求或响应,包括body实体,都是在调用处理程序之前加载的。也许你不想这样,YMMV。

Netty 4会自动在你创建的管道上添加最后一个处理程序,如果事件到达最后一个处理程序,它会通过消息。最后一个入站处理程序不应触发上下文事件

删除此项:
ctx.fireChannelRead(msg)

@eskatos是对的,管道的处理程序基于类型匹配,例如,
SimpleChannelInboundHandler
将只处理HttpContent,如果您尚未处理HttpReport(将
SimpleChannelInboundHandler
添加到管道中),Netty将发出警告:内容长度:
,到达管道尾部。请检查您的管道配置

因此,解决方案是将相应的
ChannelInboundHandler/ChannelOutboundHandler
添加到管道中

但您首先需要知道类型化处理程序缺少什么: 找到DefaultChannelPipeline的channelRead方法并调试到其中,以获取包含消息所缺少内容的msg.content().toString()

还有一件事,@
Norman Maurer
提到的启用调试日志记录的方法不起作用,因为channelRead方法不会记录msg内容中的内容

下面是DefaultChannelPipeline的channelRead方法(Netty 4.1):


谢谢,这或多或少是我认为它的意思,但我正在寻找关于如何探索解决方案的建议。在我的例子中(如运行main.scala的repo中所示),在发送方和接收方都为http设置了管道,并且发送的消息是http。你能建议如何进行探索吗?“配置错误”是一个非常通用的概念。还可以以某种方式提取假定未经处理的消息吗?在netty中启用调试日志记录,它应该在问题正文中记录要删除的消息的类型添加日志记录输出。没有得到太多的日志信息。我是否应该以其他方式启用日志记录?Netty在调试级别记录丢弃的入站消息。使用4.0.0.Beta3,我得到以下日志:“调试io.netty.channel.DefaultChannelPipeline-丢弃入站消息io.netty.handler.codec.http.LastHttpContent”$1@b68d372已到达管道末尾。请检查管道配置。“”那么,为什么会在客户端发出丢弃消息警告?您的回答不意味着问题出在服务器端的解码器上吗?我错过了什么?谢谢据我所知,这对服务器和客户端都是正确的。两者都使用HttpCodec并以相同的方式工作。我编辑了我的答案以澄清这一点。不确定这如何适用于编辑后的答案中的客户端(您是说客户端从服务器接收到LastHttpContent对象,从而发出警告?)。我期望客户端接收http响应,而不是http请求。是的,在我的回答中,有一个地方我没有将HttpResponse放在HttpRequest旁边。我再次编辑了它来修复这个问题,并添加了一些内容,以明确服务器或客户端不重要(只需交换*请求*响应)。谢谢您提供的信息。最大尺寸应该是多少?
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            logger.debug(
                    "Discarded inbound message {} that reached at the tail of the pipeline. " +
                            "Please check your pipeline configuration.", msg);
        } finally {
            ReferenceCountUtil.release(msg);
        }
    }