java中logger关闭log_Log4J如何关闭Logger对象的IO流资源

之前,在做一个项目时,客户要求在接口中对各个交易每天在monitor、trans、service三个目录下生成日志文件,monitor按日期生成文件碎片,trans每天按照日期生成一个目录,在该目录下再按照日期+交易号生成文件碎片,service也是按照日期生成目录,然后再目录下用日期+交易号生成文件碎片。由于自己对于log4J不熟悉,自己想如果每个交易都配置一个,那么日志文件配置好几十个log,使得配置文件过于庞大,于是自己便对日志对象做封装,在Socket接口中放一个日志对象队列,每次进入接口中去日志队列中搜索Logger对象,隔天切换之前的日志对象,按照这样的想法顺利实现了日志要求,项目压力测试时系统时间切换一周,没有任何问题,项目顺利上线。但是,生产中项目跑了1个月后,问题出现了,突然一天早上,客户的科技告诉我交易突然不能完成,服务器向监控平台报告异常了,去机房查看日志,系统报了java.net.SocketException:too many open files。

首先,由于项目并没有太多的对除日志文件之外的文件操作,总共也就那么几个配置文件,而且所有IO资源都关闭了,所以可以排除本地文件IO的问题。其次,异常发生的时候除了心跳报文外,其他的交易都没有发生,没有大规模并发的现象,可以排除网络IO的原因。剩下最有可能引发异常就是日志了,虽然每天的日志对象都从队列中remove了,但是被remove掉的Logger的资源是否立刻被回收了呢?

两台服务器的was上配置JVM的内存都是2G,而服务实际上占用的资源不到200M(疲劳测试的得出),这事JVM在内存充足的情况下,并不能够立即将不用的Logger对象GC掉,被抛弃的Logger对象中所占的IO资源并没有关闭,那么怎样才能关闭这些Logger对象的IO资源。在网上查找了一番,看到上善若水的一片名为《深入Log4J源码之Log4J Core》的博文,Log4J核心接口为Logger、LoggerRepository、Level、LoggingEvent、Appender、Layout、ObjectRender。自己想Log4J的关闭IO资源的操作应该是在在这几个接口中,挨个去查找Log4J的API,果然在Appender类的方法列表有close方法,close方法的描述为Release any resources allocated within the appender such as file handles, network connections, etc.

于是在remove Logger对象时候,调用getAllAppenders获取所有Appenders,然后挨个close。打包测试,问题解决了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值