2013-10-28 17 views
12

Tôi có một ứng dụng chạy trên tomcat và đôi khi tôi có lỗi dưới đây:Lỗi trong tomcat "quá nhiều tập tin mở"

SEVERE: Socket accept failed 
java.net.SocketException: Too many open files 
at java.net.PlainSocketImpl.socketAccept(Native Method) 
at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:398) 
at java.net.ServerSocket.implAccept(ServerSocket.java:522) 
at java.net.ServerSocket.accept(ServerSocket.java:490) 
at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:60) 
at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:216) 
at java.lang.Thread.run(Thread.java:722) 

....

SEVERE: Error processed default web.xml named conf/web.xml at /local/myApp/apache-tomcat/conf/web.xml 
java.io.FileNotFoundException: /local/myApp/apache-tomcat/conf/web.xml (Too many open files) 
     at java.io.FileInputStream.open(Native Method) 
     at java.io.FileInputStream.<init>(FileInputStream.java:138) 
     at org.apache.catalina.startup.ContextConfig.getWebXmlSource(ContextConfig.java:1838) 
     at org.apache.catalina.startup.ContextConfig.getGlobalWebXmlSource(ContextConfig.java:1745) 
     at org.apache.catalina.startup.ContextConfig.getDefaultWebXmlFragment(ContextConfig.java:1418) 
     at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1253) 
     at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:878) 
     at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:369) 
     at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119) 
     at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90) 
     at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5269) 
     at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) 
     at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3926) 
     at org.apache.catalina.loader.WebappLoader.backgroundProcess(WebappLoader.java:426) 
     at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1345) 
     at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1530) 
     at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540) 
     at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540) 
     at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1519) 
     at java.lang.Thread.run(Thread.java:722) 

tôi kiểm tra các giới hạn của các tập tin mở và nó là 1024 nhưng khi tôi kiểm tra số lượng các tập tin mở của ứng dụng với lsof nó gần 200, tại sao điều này xảy ra nếu nó không đạt đến giới hạn? Tôi có nên tăng giới hạn không? Có lý do nào khác để nhận lỗi này không? Cách duy nhất để dịch vụ chạy đúng một lần nữa, nó khởi động lại tomcat, có cách nào khác để lấy lại bình thường không?

Xin cảm ơn trước.

EDIT: Đây là servlet xử lý phương thức doPost, lúc đầu tôi không đóng mọi luồng, có phải vậy không? Tôi được thêm vào cuối cùng tuyên bố để làm điều đó:

InputStream is = null; 
    DataInputStream dis = null; 
    OutputStream os = null; 
    DataOutputStream dos = null; 
    String paramName = ""; 
    try { 
     os = response.getOutputStream(); 
     is = request.getInputStream(); 
     dis = new DataInputStream(is); 
     dos = new DataOutputStream(os); 
     ..... 
     }catch (Throwable e) { 
     LOGGER.error(e.getMessage()); 
     } finally { 
      if (dis != null) { 
      dis.close(); 
      } 
      else if(is != null) { 
      is.close(); 
      }     
      if (dos != null) { 
      dos.close(); 
      } 
      else if(os != null) { 
      os.close(); 
      } 
     } 

EDIT2: Sau khi thực hiện một số thử nghiệm tôi nhận ra rằng nếu tôi đóng đầu tiên DataInputStream và sau đó là InputStream, tôi nhận được trong một phần khác của giao tiếp một số trước tin nhắn (Tôi không biết tại sao). Tôi đã thay đổi thứ tự đóng luồng và dường như mọi thứ đều ổn. Nhưng tôi vẫn có vấn đề. Bất kỳ ý tưởng?

finally { 

    if(is != null) { 
     try { 
      is.close(); 
     } catch (IOException e) { 
      LOGGER.error(e.getMessage()); 
     } 
    } 
    if (dis != null) { 
     try { 
      dis.close(); 
     } catch (IOException e) { 
      LOGGER.error(e.getMessage()); 
     } 
    } 
    if(os != null) { 
     try { 
      os.close(); 
     } catch (IOException e) { 
      LOGGER.error(e.getMessage()); 
     } 
    } 
    if (dos != null) { 
     try { 
      dos.close(); 
     } catch (IOException e) { 
      LOGGER.error(e.getMessage()); 
     } 
    } 
} 
+0

Có, tôi đã kiểm tra trang web này, nhưng dịch vụ cũng không sử dụng quá 200 tối đa, tại sao tăng đến 4096 giới hạn? – alicia

+0

Bạn nên tìm kiếm lỗi của mình trên trang web trước tiên: http://stackoverflow.com/questions/5656458/java-net-socketexception-too-many-open-files – developerwjk

+0

Chia sẻ mã của bạn! chúng tôi không thể giúp đỡ mà không có bất kỳ đoạn mã nào. – tokhi

Trả lời

6

Nó có thể hữu ích để biết rằng bạn có thể thay đổi giới hạn các file mở bằng cách thêm dòng sau vào /etc/security/limits.conf:

* soft nofile 2048 # Set the limit according to your needs 
* hard nofile 2048 

Sau đó, bạn có thể tải lại cấu hình sử dụng sysctl -p trên vỏ. Kiểm tra this article.

Chỉ cần cho đầy đủ, bạn có thể xác minh các giới hạn hiện tại cho các tập tin mở sử dụng là gì: ulimit -n

9

Làm như sau để có được pid, nói 1234, của tomcat7

ps aux |grep tomcat7 

và sau đó làm

cat /proc/1234/limits để đọc một dòng như sau

Max open files 16384 16384 files

Đây là số lượng tệp mở tối đa được Tomcat cho phép. Để tăng nó, hãy làm theo các hướng dẫn dưới đây

Too many open files Tomcat.

+1

Tôi đã kiểm tra và tăng số lượng tệp đang mở lên số không thể truy cập được. Tôi nghĩ rằng nó là một quản lý xấu của các chủ đề bên trong ứng dụng, nó có thể được? – alicia

+1

Có, tôi đoán rằng có thể bạn đang làm rò rỉ các trình xử lý tệp/kết nối trong ứng dụng của mình. – Zouzias

+0

Có cách nào để xem danh sách các tệp đang mở đó không? Và sẽ hữu ích để xem những gì thread đã mở chúng. –

0
  1. Nếu mã này là từ các hoạt động ròng (socket), Tôi không chắc chắn Java XxxxxStrem có 1: 1 liên quan đến giới hạn tập tin hệ điều hành (hoặc có mối quan hệ ở tất cả). Có lẽ cần một số nghiên cứu, thông báo ngoại lệ có văn bản sai? Khá thường xuyên trong phần mềm.

  2. Trực giác của tôi nói rằng, chúng tôi không hiểu Ngoại lệ 2, không có gì trong mã (hoặc cấu hình vắng mặt được đề cập) có quan hệ.

  3. Mở rộng các file hệ điều hành hạn chế khi lỗi phần mềm (rò rỉ) là vấn đề chính là chính sách xấu, như Bạn tốt hiểu

2

Câu trả lời @gaboroncancio gửi về cơ bản là đúng, nhưng lời khuyên của ông về cách làm cho các cài đặt có hiệu lực không hoàn toàn đúng. sysctl -p sẽ tải lại /etc/sysctl.conf hoặc bất kỳ tệp nào bạn chuyển vào làm đối số. Tuy nhiên, lệnh sysctl sẽ không nhận dạng được /etc/security/limits.conf.

Để tải lại /etc/security/limits.conf, bạn chỉ cần đăng xuất và đăng nhập lại.

+0

Có tải lại giá trị cần đăng nhập lại –

1

này sẽ hiển thị tất cả các file mở của quá trình đó.

ls -l /proc/tomcatPID/fd 

Điều này sẽ hiển thị số lượng tệp đang mở.

ls -l /proc/tomcatPID/fd | wc -l 

Để tăng các tệp đang mở giới hạn cập nhật /etc/Secirity/limits.conf.

Để kiểm tra không có các tập tin mở cụ thể để tomcat:

giới hạn cứng: su - tomcat -c 'ulimit -Hn' -s '/bin/bash'

giới hạn mềm: su - tomcat -c 'ulimit -Sn' -s '/bin/bash'

Bạn có thể chạy dưới kịch bản với một công việc ngô để biết các chi tiết của tập tin đang mở .

============================= 
#!/bin/bash 

PID=$(ps -ef|grep tomcat6|grep -v grep |awk '{print $2}') 
value=$(ls -l /proc/$PID/fd | wc -l) 
echo `date`@$PID:$value >> /usr/local/filecount.txt 
if [ $value -gt 2000 ]; 
then 
printf "\n\n\n\n\n" >> /usr/local/files_report.txt 
echo "-------------------------------`date`--Starting Session----------------------" >> /usr/local/files_report.txt 
openfiles=$(ls -l /proc/$PID/fd | awk '{print NR,$11 "" >> "/usr/local/files_report.txt"}') 
echo "--------------------`date`---Ending Session ------------------------------" >> /usr/local/files_report.txt 
fi 
================= 
+0

Định dạng tốt. – Billa

Các vấn đề liên quan