定位线程异常

问题现象:发现服务上线后,内存使用率随着小时持续攀升,然后到达阈值后直接服务重启然后再循环反复

问题原因猜测:线程池多任务执行完毕后发现,有线程未正常关闭,依旧存在,且每次执行这块代码持续叠加,没有成功GC掉最终导致内存爆满直接服务重启

解决步骤

1,任务持续等待资源导致连接超时,且偶尔日志会报连接es服务超时

CredentialsProvider provider = new BasicCredentialsProvider();
        provider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("***", "***"));
        RestClient restClient = RestClient.builder(new HttpHost("*.*.*.*", 80,"http"))
                .setHttpClientConfigCallback(builder -> {
                    return builder.setDefaultCredentialsProvider(provider);
                }).build();
        ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
        ElasticsearchClient client = new ElasticsearchClient(transport);

        这里是代码每次执行都创建的es客户端,怀疑是查询es服务端波动导致服务超时,

本地测试直接改为长连接测试虽然没有报错日志了但依旧不能解决

RestClient restClient = RestClient.builder(new HttpHost("*.*.*.*", 80,"http"))
                .setHttpClientConfigCallback(builder -> builder
                        .setDefaultCredentialsProvider(provider)
                        .setKeepAliveStrategy(((httpResponse, httpContext) -> Duration.ofMinutes(3).toMillis()))
                )
                .build();

2,怀疑任务没有关闭导致用例池没正常释放,这里直接在finally里强制关闭,也无法解决

pool.shutdownNow();

3,对线程进行单独命名,然后去堆栈日志里查询是否正常释放

ExecutorService pool = new ThreadPoolExecutor( 20,200, 0L,  TimeUnit.SECONDS,  new LinkedBlockingQueue<>(10240), new BasicThreadFactory.Builder().namingPattern("use-task-executor-%d").daemon(true).build());

        打开对应实例终端 寻找JDK对应位置  which java

        

        进入对应bin目录 检查下是否有jstack  有的话使用ps -ef|grep java查看到对应的java进程,使用 jstack PID 查看进程下所有线程的使用情况

        查看该用例池自定义的线程有没有释放

这里发现线程池里的线程都正常释放了

然后分析堆栈日志后发现,状态最多的线程es连接的线程一直在运行

这里就定位到了,每次请求都会创建线程池大小数量的es连接请求,关闭线程池并不会关闭里面关于es连接的进程,加上代码

finally {
            if(null != restClient){
                restClient.close();
            }
            if(null != transport){
                transport.close();
            }
        }

 然后重新上线查看线程情况,线程使用后正常释放,没有持续爬坡的情况了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值