我们将二进制编码的数据作为JSON请求的有效负载发送到Netty后端。在较小的有效负载(1-2MB)上,一切正常,但在较大的有效负载上,它会失败,并出现错误
HTTP 413 Request entity too large
.
我们发现有两个地方会受到影响:
-
HttpObjectAggregator
-
的构造函数
JsonObjectDecoder
正文分析器。
我们已将第一个设置为高于问题阈值(10MB)的默认方式(5MB),而后者我们根本不使用,因此我们不确定如何深入研究。
(顺便说一句,我们打算将来不要对大型二进制有效负载使用JSON,因此不需要关于更改底层体系结构的“有用”提示;-))
管道设置
我们有两个管道初始化阶段,第一个阶段取决于http协议版本和SSL的组合,后一个阶段只涉及应用程序级处理程序。
PipelineInitializer
/**
* This class is concerned with setting up the handlers for the protocol level of the pipeline
* Only use it for the cases where you know the passed in traffic will be HTTP 1.1
*/
public class Http1_1PipelineInitializer implements PipelineInitializer {
private final static int MAX_CONTENT_LENGTH = 10 * 1024 * 1024; // 10MB
@Override
public void addHandlersToPipeline(ChannelPipeline pipeline) {
pipeline.addLast(
new HttpServerCodec(),
new HttpObjectAggregator(MAX_CONTENT_LENGTH),
new HttpChunkContentCompressor(),
new ChunkedWriteHandler()
);
}
}
ApplicationPipelineInitializer中的应用程序级管道设置。我不认为这些是相关的,但包括完整性。此部分中的所有处理程序都是用户定义的处理程序:
@Override
public void addHandlersToPipeline(final ChannelPipeline pipeline) {
pipeline.addLast(
new HttpLoggerHandler(),
userRoleProvisioningHandler,
authHandlerFactory.get(),
new AuthenticatedUserHandler(services),
createRoleHandlerFactory(configuration, services, externalAuthorizer).get(),
buildInfoHandler,
eventStreamEncoder,
eventStreamDecoder,
eventStreamHandler,
methodEncoder,
methodDecoder,
methodHandler,
fileServer,
notFoundHandler,
createInterruptOnErrorHandler());
// Prepend the error handler to every entry in the pipeline. The intention behind this is to have a catch-all
// outbound error handler and thereby avoiding the need to attach a listener to every ctx.write(...).
final OutboundErrorHandler outboundErrorHandler = new OutboundErrorHandler();
for (Map.Entry<String, ChannelHandler> entry : pipeline) {
pipeline.addBefore(entry.getKey(), entry.getKey() + "#OutboundErrorHandler", outboundErrorHandler);
}
}
Netty版本4.1.15