栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

ES查询报错:entity content is too long [142501157] for the configured buffer limit [104857600]

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ES查询报错:entity content is too long [142501157] for the configured buffer limit [104857600]

java - org.apache.http.ContentTooLongException: entity content is too long [105539255] for the configured buffer limit [104857600] - Stack Overflow

在生产环境批量同步数据的时候,我写了一个查询请求,然后直接报错:entity content is too long [142501157] for the configured buffer limit [104857600]

具体内容如下:

Caused by: org.apache.http.ContentTooLongException: entity content is too long [142501157] for the configured buffer limit [104857600]
        at org.elasticsearch.client.HeapBufferedAsyncResponseConsumer.onEntityEnclosed(HeapBufferedAsyncResponseConsumer.java:76)
        at org.apache.http.nio.protocol.AbstractAsyncResponseConsumer.responseReceived(AbstractAsyncResponseConsumer.java:137)
        at org.apache.http.impl.nio.client.MainClientExec.responseReceived(MainClientExec.java:315)
        at org.apache.http.impl.nio.client.DefaultClientExchangeHandlerImpl.responseReceived(DefaultClientExchangeHandlerImpl.java:151)
        at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.responseReceived(HttpAsyncRequestExecutor.java:315)
        at org.apache.http.impl.nio.DefaultNHttpClientConnection.consumeInput(DefaultNHttpClientConnection.java:255)
        at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:81)
        at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:39)
        at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:114)
        at org.apache.http.impl.nio.reactor.baseIOReactor.readable(baseIOReactor.java:162)
        at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:337)
        at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315)
        at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:276)
        at org.apache.http.impl.nio.reactor.baseIOReactor.execute(baseIOReactor.java:104)
        at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:591)
        at java.lang.Thread.run(Thread.java:748)
        Suppressed: org.apache.http.ContentTooLongException: entity content is too long [142501157] for the configured buffer limit [104857600]
                ... 16 more
                Suppressed: org.apache.http.ContentTooLongException: entity content is too long [142501157] for the configured buffer limit [104857600]
                        ... 16 more

在HttpAsyncResponseConsumerFactory类中:

在HeapBufferedAsyncResponseConsumer类中有一个判断:返回的内容长度大于限定的100MB就会抛出ContentTooLongException异常。

我这里用的依赖是:

            
                org.elasticsearch.client
                elasticsearch-rest-client
                6.6.2
            

            
                org.elasticsearch.client
                transport
                6.6.2
            

            
                org.elasticsearch.client
                elasticsearch-rest-high-level-client
                6.6.2
            

            
                org.elasticsearch
                elasticsearch
                6.6.2
            

而我们对es进行查询操作,或者其他增删改操作是,都会默认使用如下的RequestOptions.DEFAULT

进入RequestOptions.DEFAULT看它的代码:这里用了HeapBufferedResponseConsumerFactory.DEFAULT

而这个HeapBufferedResponseConsumerFactory.DEFAULT,就是我们之前看到的,已经被限制了100MB返回值的HeapBufferedResponseConsumerFactory。

所以有两种方式可以解决这个bug。

方式一:

不使用默认的RequestOptions.DEFAULT,而通过使用自定义RequestOptions的方式(ES官方api已经给我们开放出来了):

RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
builder.setHttpAsyncResponseConsumerFactory(
    new HttpAsyncResponseConsumerFactory
    //修改为500MB
    .HeapBufferedResponseConsumerFactory(500 * 1024 * 1024));

RequestOptions requestOptions=builder.build();

方式二:

如果不方便修改怎么办,例如我们使用的是Spring Data ElasticSearch或者是其他的一些框架,而它默认使用的也是RequestOptions.DEFAULT

这时候我们可以通过java反射进行修改:

        //设置es查询buffer大小
        RequestOptions requestOptions = RequestOptions.DEFAULT;
        Class reqClass = requestOptions.getClass();
        Field reqField = reqClass.getDeclaredField("httpAsyncResponseConsumerFactory");
        reqField.setAccessible(true);
        //去除final
        Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField.setInt(reqField, reqField.getModifiers() & ~Modifier.FINAL);

        //设置默认的工厂
        reqField.set(requestOptions, new HttpAsyncResponseConsumerFactory() {
            @Override
            public HttpAsyncResponseConsumer createHttpAsyncResponseConsumer() {
                //500MB
                return new HeapBufferedAsyncResponseConsumer(5 * 100 * 1024 * 1024);
            }
        });

如果你使用的是springmvc,那么可以把这段代码加入到拦截器中,这样可以拦截需要自定义返回值大小的es请求

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/678407.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号