我有一个运行java应用程序的tomcat,偶尔会累积套接字句柄并达到我们为max-open-files配置的ulimit(软和硬),这是100K.当发生这种情况时,java似乎仍然存在,但我们无法再访问它.
但是我的问题是关于这种情况伴随的奇怪现象:我不能在tomcat文件夹中使用mkdir.
[root@server /opt/apache-tomcat-7.0.52]# mkdir some_folder mkdir: cannot create directory `some_folder': No space left on device
实际上,我在/ opt下的多个不同文件夹下得到了同样的错误,但是没有直接在/ opt下,而不是 – 例如 – 在/opt/apache-tomcat-7.0.52/logs下.
我无法解释它为我的生活,并且只能使用init 6解决.有关如何解决问题的任何建议,并能够重新启动mkdir吗?
我收集的一些指示和线索:
该设置是在AWS下运行的CentOS 6.5,其中所述tomcat磁盘是从EBS卷安装的.
运行df -h表明磁盘显然未满:
[root@server ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda1 9.9G 3.6G 5.9G 38% / none 121G 0 121G 0% /dev/shm /dev/xvdc 1008G 197G 760G 19% /mnt/eternal
/ etc / fstab的内容(出于某种原因,使用双重安装 – 不确定原因):
/dev/xvdc /mnt/eternal ext4 defaults 0 0 /mnt/eternal /opt ext4 defaults,bind 0 0
来自mount的适当行:
/dev/xvdc on /mnt/eternal type ext4 (rw) /mnt/eternal on /opt type none (rw,bind)
运行df -i并不暗示坏事(并且类似于健康的系统):
[root@server ~]# df -i Filesystem Inodes IUsed IFree IUse% Mounted on /dev/xvda1 655360 78245 577115 12% / none 31549847 1 31549846 1% /dev/shm /dev/xvdc 67108864 12551 67096313 1% /mnt/eternal
运行sysctl fs.file-nr给出的结果显然很高但似乎远离限制:
[root@server ~]# sysctl fs.file-nr fs.file-nr = 101632 0 25087252
运行find / proc | wc -l返回62497876(62M),可能达到一些操作系统限制;在类似的健康系统上,它更像1800000(1.8M).
占用量很大的子文件夹似乎是/ proc /< my-java-pid> / task(约62M项目与健康系统上的~1.7M相比).这可能只反映了我的100K fds(x2,对于fds和fdinfos)超过300个单独的“任务”文件夹.
这出现在我的dmesg转储结束时(我的java pid在这个例子中是105940) – 不确定这可能是如何关联的:
INFO: task java:105940 blocked for more than 120 seconds. "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. java D 0000000000000008 0 105940 1 0x00000080 ffff88161ab55c88 0000000000000082 ffff88161ab55c18 ffffffff8109be4f ffffffff81ed28f0 ffff881e66360ae0 ffffffff8100bb8e ffff88161ab55c88 ffff881e66361098 ffff88161ab55fd8 000000000000fb88 ffff881e66361098 Call Trace: [<ffffffff8109be4f>] ? hrtimer_try_to_cancel+0x3f/0xd0 [<ffffffff8100bb8e>] ? apic_timer_interrupt+0xe/0x20 [<ffffffff810521c9>] ? mutex_spin_on_owner+0x99/0xc0 [<ffffffff8151636e>] __mutex_lock_slowpath+0x13e/0x180 [<ffffffff8151620b>] mutex_lock+0x2b/0x50 [<ffffffff8111c461>] generic_file_aio_write+0x71/0x100 [<ffffffffa0121fb1>] ext4_file_write+0x61/0x1e0 [ext4] [<ffffffff81180d7a>] do_sync_write+0xfa/0x140 [<ffffffff81096ca0>] ? autoremove_wake_function+0x0/0x40 [<ffffffff812292ab>] ? selinux_file_permission+0xfb/0x150 [<ffffffff8121bd26>] ? security_file_permission+0x16/0x20 [<ffffffff81181078>] vfs_write+0xb8/0x1a0 [<ffffffff81181971>] sys_write+0x51/0x90 [<ffffffff81517e2e>] ? do_device_not_available+0xe/0x10 [<ffffffff8100b072>] system_call_fastpath+0x16/0x1b
我很乐意分享/提供任何其他建议的发现.
暗地里,我希望理解这种奇怪的行为能够揭示导致整个混乱的病态.但是,这只是我的私人希望:)
解决方法
简短的回答:卸载磁盘,在其上运行chkdsk -f,然后重新安装,解决并防止问题再次发生.作为替代方案,创建一个新磁盘(记住我们在AWS上)并将所有数据复制到新磁盘(rsync -a是我选择的命令)并使用它来替换原始磁盘也解决了&阻止.
更长的答案:磁盘文件系统(ext4)在最初创建磁盘快照时似乎已达到某种不稳定状态.稍后将200GB的原始快照(使用resize2fs)扩展到1TB时,似乎在某种意义上它会在内部记住200GB的原始大小,从而产生各种奇怪的现象,最终导致操作系统无法关闭句柄,从而使Tomcat达到其文件限制,因此完全崩溃了.
最长的答案,更多的侦探工作细节:当我们在两个单独的设置上并行发生这种病理时,突破发生了.检查这些设置和比较的所有参数,我们意识到驱动器上的df -h显示了这个结果:
/dev/xvdc 1008G 197G 760G 19% /mnt/eternal
现在,之前没有引起我们的注意,因为磁盘仍然有足够的空间.但两种设置的磁盘使用情况完全相同(197G),没有理由这样做.从这里开始,事情很快就展开了.如前所述,我们的AWS实例是从具有200GB磁盘快照的映像创建的,该映像使用resize2fs在各个实例上进行扩展 – 通常最大为1TB.我们终于能够通过启动一个新实例重新创建一个“坏状态”,调整大小到1TB,并创建一个300GB的大文件.完成后,系统没有冻结,但确实显示了同样的奇怪行为:
/dev/xvdc 1008G 197G 760G 19% /mnt/eternal
当磁盘上显然有超过197GB的数据时.因此,我们在两个单独的干净设置上尝试了上面提到的两种方法(chkdsk并重新创建磁盘),并且在每种方法上都不再出现奇怪的行为.
我们最好的猜测是,在某些时候,当AMI创建时,快照过程出现问题 – 很可能是因为我们拍摄了“没有重启的快照”(虽然我们通常不会,但我没有证据支持这个,所以我希望我们的DevOps不会因为我无缘无故地责怪她而生气!).总而言之,这是一次有趣的体验.