开发错误总结之---循环创建ES批处理客户端造成的OOM异常

刚刚在整理之前的帖子挪到知乎的时候,整理到了批处理客户端的帖子,突然想起来,去年的七月份,我第一次用这个批处理客户端,当时在生产上大约一周多点点,运维告诉我程序出异常了,出现了OOM异常

OOM异常,out of memory,内存溢出

当时觉得很奇怪,用了各种办法,手动提醒GC,用完的集合清空等等,都没用,且本地不复现

后来,本地测试的时候,我用Jconsole查看了一下程序的运行时状况,我发现线程数一直在涨,一直再涨,没有降过,并且涨的很离谱

于是我运行了别的程序,发现线程数稳定在120-190之间,但是我的这个程序线程数已经到了2000+

我限定了程序内存,发现线程数超过 2500+的时候,果然OOM了

于是我开始找,找遍了各个地方,都没问题,最后发现,我在循环里不断的创建ES高级批处理客户端,就是下边这个东西

/*
     * 创建bulkProcessor
     * */
    public BulkProcessor bulkProcessor(String taskTypeLog) {
        BiConsumer<BulkRequest, ActionListener<BulkResponse>> bulkConsumer =
                (request, bulkListener) -> restHighLevelClient.bulkAsync(request, RequestOptions.DEFAULT, bulkListener);
 
        return BulkProcessor.builder(bulkConsumer, new BulkProcessor.Listener() {
            @Override
            public void beforeBulk(long executionId, BulkRequest request) {
                //在这儿你可以自定义执行同步之前执行什么
            }
 
            @SneakyThrows
            @Override
            public void afterBulk(long executionId, BulkRequest request, BulkResponse response) {
                //在这儿你可以自定义执行完同步之后执行什么
            }
 
            @Override
            public void afterBulk(long executionId, BulkRequest request, Throwable failure) {
                //写入失败后
                log.error("ES写入失败", failure);
            }
        }).setBulkActions(10000) //  达到刷新的条数
                .setFlushInterval(TimeValue.timeValueSeconds(10) // 固定刷新的时间频率
                .build();
    }

 

我猜测可能是这个,因为是个客户端,属于重量级的东西,会比较消耗资源,并且因为是客户端,可能是一种守护进程,或长连接

于是我想办法将这个改为了共用的,只创建一次

再次限定内存,运行程序,检测程序的运行情况

线程数稳定在150左右

OK,问题解决

总结出来的经验:客户端、工厂、生产者,都属于比较耗资源的重量级玩意,一定要慎重,不要频繁创建,如果出现了问题,先看看代码,然后走监控,一步一步看

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值