mina 文件句柄數太高分析與解決

Part1部分是一位博友辛苦做出的分析,貼出來。

之後是part2是給出如何解決下面的報錯問題


Part1

2014-11-01 19:43:12,997  WARN (AbstractConnector.java:472) - 

java.io.IOException: Too many open files
at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:226)
at org.eclipse.jetty.server.ServerConnector.accept(ServerConnector.java:336)
at org.eclipse.jetty.server.AbstractConnector$Acceptor.run(AbstractConnector.java:467)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:607)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:536)
at java.lang.Thread.run(Thread.java:722)


Last login: Sat Nov  1 17:35:34 2014 from 220.184.86.17
[root@www ~]# free
             total       used       free     shared    buffers     cached
Mem:      16282708   16127828     154880          0       9148   13197512
-/+ buffers/cache:    2921168   13361540
Swap:      8208376          0    8208376

上週五20:22左右,服務器突然掛掉,LOG裏全是“java.io.IOException: Too many open files”。
我在週六16點多重啓服務器以後,第二天發現在週六19:36左右的時候,又掛掉了,現象完全一樣。
掛掉時,free很少,cached很多。這次,我沒有重啓服務器,而是清除了一下cache,就恢復了。

從服務器的流量圖中可以看到,從上週五開始,流入的流量(藍色線)突然飈的很高。
而之前,它都是維持在很低的水平的,感覺像遭受了攻擊一樣。這個還要再分析了。
從年流量圖上看,8月份(Aug)流入的流量也很高,這估計是因爲8月中才加的防火牆:


[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. // 查看定時日誌,發現20點以前都是好的,21點以後就掛了(內存耗盡,文件句柄用光)  
  2. # cat /home/lsofc.log  
  3. ===========================  
  4. 2014年 11月 07日 星期五 16:00:01 CST  
  5. Memory usage | [Use:5782 MB][Free:10118 MB][Cached:3942 MB]   
  6. File count | [All count:6957][JAVA count:912]   
  7. ===========================  
  8. 2014年 11月 07日 星期五 17:00:01 CST  
  9. Memory usage | [Use:5806 MB][Free:10094 MB][Cached:3950 MB]   
  10. File count | [All count:5855][JAVA count:864]   
  11. ===========================  
  12. 2014年 11月 07日 星期五 18:00:02 CST  
  13. Memory usage | [Use:5807 MB][Free:10093 MB][Cached:3957 MB]   
  14. File count | [All count:5717][JAVA count:980]   
  15. ===========================  
  16. 2014年 11月 07日 星期五 19:00:01 CST  
  17. Memory usage | [Use:5789 MB][Free:10110 MB][Cached:3951 MB]   
  18. File count | [All count:5837][JAVA count:1106]   
  19. ===========================  
  20. 2014年 11月 07日 星期五 20:00:01 CST  
  21. Memory usage | [Use:5830 MB][Free:10070 MB][Cached:3994 MB]   
  22. File count | [All count:6115][JAVA count:1033]   
  23. ===========================  
  24. 2014年 11月 07日 星期五 21:00:01 CST  
  25. Memory usage | [Use:14002 MB][Free:1898 MB][Cached:11084 MB]   
  26. File count | [All count:70417][JAVA count:65718]   
  27. ===========================  
  28. 2014年 11月 07日 星期五 22:00:01 CST  
  29. Memory usage | [Use:15732 MB][Free:169 MB][Cached:12875 MB]   
  30. File count | [All count:70406][JAVA count:65718]   
  31. ===========================  
  32. 2014年 11月 07日 星期五 23:00:01 CST  
  33. Memory usage | [Use:15749 MB][Free:150 MB][Cached:12847 MB]   
  34. File count | [All count:70394][JAVA count:65718]   
  35.   
  36. // 服務器掛掉後,查看各種信息  
  37. # free -m  
  38.              total       used       free     shared    buffers     cached  
  39. Mem:         15901      15742        158          0        127      12784  
  40. -/+ buffers/cache:       2830      13070  
  41. Swap:         8015          2       8013  
  42. // 打開的文件數,超出了限制(65536)  
  43. # lsof -n | wc -l  
  44. 70091  
  45. // 網絡相關的文件句柄數,也非常多  
  46. # lsof -n -i | wc -l  
  47. 62548  
  48. // 網絡連接數,也非常多  
  49. # netstat -ant | wc -l  
  50. 63777  
  51. // 端口爲54104的連接數,也非常多  
  52. # netstat -ant | grep ":54104" | wc -l  
  53. 61101  
  54. // 查看端口爲54104的各種狀態的連接數,發現CLOSE_WAIT的超多  
  55. # netstat -ant | grep ":54104" | awk '{print $6}' | sort | uniq -c  | sort -nr   
  56.   54166 CLOSE_WAIT  
  57.    6920 ESTABLISHED  
  58.      10 SYN_RECV  
  59.       1 LISTEN  
  60.   
  61. // 所有網絡連接數,按狀態排序  
  62. # netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print S[a],a}' | sort -nr   
  63. 54184 CLOSE_WAIT  
  64. 8239 ESTABLISHED  
  65. 926 FIN_WAIT2  
  66. 207 FIN_WAIT1  
  67. 64 TIME_WAIT  
  68. 46 LAST_ACK  
  69. 31 SYN_RECV  
  70. 1 CLOSING  
  71. // 所有打開文件數,按進程PID排序  
  72. # lsof -n | awk '{print $2}' | sort -n | uniq -c | sort -nr | more  
  73.   65605 18374  
  74.     741 1348  
  75.     313 1349  
  76.     236 1350  
  77.     149 18407  
  78. // 發現確實是JAVA進程搞的鬼  
  79. # jps  
  80. 18374 DesktopServerLauncher  
  81. 14690 Bootstrap  
  82. // 關閉的JAVA進程  
  83. # ./shutdown.sh   
  84. shutting down  
  85. killing pid 18374  
  86. process has been shutdown  
  87. // 查看一下,確實關閉了  
  88. # jps  
  89. 14690 Bootstrap  
  90. 25788 Jps  
  91. // 再查看打開文件數,就少了JAVA進程的了  
  92. # lsof -n | awk '{print $2}' | sort -n | uniq -c | sort -nr | more  
  93.     637 1348  
  94.     547 1349  
  95.     296 1350  
  96.     126 1336  
  97.     112 14690  
  98.      86 25007  
  99. // 重啓JAVA進程  
  100. # ./startup.sh   
  101. starting from ./boot.sh ...       
  102. // 查看一下,確實重啓了  
  103. #jps  
  104. 25829 DesktopServerLauncher  
  105. 14690 Bootstrap  
  106. 25893 Jps  
  107. // 剛啓動,其打開的文件數,並不多(428)  
  108. # lsof -n | awk '{print $2}' | sort -n | uniq -c | sort -nr | head -5  
  109.    1056 1347  
  110.    1052 1350  
  111.    1040 1349  
  112.    1037 1348  
  113.     428 25829  
  114. // 過了很久,再查看日誌。發現:Cached很多,打開文件數很少,系統運行正常。  
  115. // 因此,得出結論:該問題與Cached無關,只跟打開的文件數太多有關係。  
  116. # tail -8 /home/lsofc.log   
  117. ===========================  
  118. 2014年 11月 07日 星期五 23:00:01 CST  
  119. Memory usage | [Use:15749 MB][Free:150 MB][Cached:12847 MB]   
  120. File count | [All count:70394][JAVA count:65718]   
  121. ===========================  
  122. 2014年 11月 08日 星期六 00:00:01 CST  
  123. Memory usage | [Use:14498 MB][Free:1404 MB][Cached:12697 MB]   
  124. File count | [All count:4272][JAVA count:232]  

由此判斷,並非系統廣播,而是遭受攻擊導致的。


Part2

解決辦法:將系統限制的文件句柄數調大~

服務器端修改:

  查看系統允許打開的最大文件數

  #cat /proc/sys/fs/file-max

  查看每個用戶允許打開的最大文件數

  ulimit -a

  發現系統默認的是open files (-n) 65535,問題就出現在這裏。

  在系統文件/etc/security/limits.conf中修改這個數量限制,

  在文件中加入內容:

  * soft nofile 65536

  * hard nofile 65536


  或者敲命令,更加方便:

  1.使用ps -ef |grep java   (java代表你程序,查看你程序進程) 查看你的進程ID,記錄ID號,假設進程ID爲12

  2.使用:lsof -p 12 | wc -l    查看當前進程id爲12的 文件操作狀況

  執行該命令出現文件使用情況爲 51000

  3.使用命令:ulimit -a   查看每個用戶允許打開的最大文件數

  發現系統默認的是open files (-n) 51000,問題就出現在這裏。

  4.然後執行:ulimit -n 51000

  將open files (-n) 51000設置成open files (-n) 51000

  這樣就增大了用戶允許打開的最大文件數


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章