1. 程式人生 > >【Linux】解決tomcat出現Too many open files(開啟的檔案過多)問題

【Linux】解決tomcat出現Too many open files(開啟的檔案過多)問題

當用linux做高併發伺服器時,會遇到"Too many open files"的錯誤。

Linux是有檔案控制代碼限制的(open files),而且Linux預設不是很高,一般都是1024,做高併發生產伺服器用其實很容易就達到這個數量。

在linux中執行ulimit -a 即可查詢linux相關的引數,如下所示:

  1. ulimit -a  
  2. core file size          (blocks, -c) unlimited  
  3. data seg size           (kbytes, -d) unlimited  
  4. scheduling priority             (-e) 0  
  5. file size               (blocks, -f) unlimited  
  6. pending signals                 (-i) 63470  
  7. max locked memory       (kbytes, -l) 64  
  8. max memory size         (kbytes, -m) unlimited  
  9. open files                      (-n) 1024  
  10. pipe size            (512 bytes, -p) 8  
  11. POSIX message queues     (bytes, -q) 819200  
  12. real-time priority              (-r) 0  
  13. stack size              (kbytes, -s) 8192  
  14. cpu time               (seconds, -t) unlimited  
  15. max user processes              (-u) 102400  
  16. virtual memory          (kbytes, -v) unlimited  
  17. file locks                      (-x) unlimited  

用ulimit命令是可以修改這些配置的

命令的格式:ulimit [-SHacdefilmnpqrstuvx] [limit]

中間的引數對應這要修改的專案。

預設最大開啟檔案數(open files)最大數為1024,修改:

ulimit -n 102400

最大值為655350

命令引數:

  1. -H 設定硬體資源限制.  
  2. -S 設定軟體資源限制.  
  3. -a 顯示當前所有的資源限制.  
  4. -c size:設定core檔案的最大值.單位:blocks  
  5. -d size:設定資料段的最大值.單位:kbytes  
  6. -f size:設定建立檔案的最大值.單位:blocks  
  7. -l size:設定在記憶體中鎖定程序的最大值.單位:kbytes  
  8. -m size:設定可以使用的常駐記憶體的最大值.單位:kbytes  
  9. -n size:設定核心可以同時開啟的檔案描述符的最大值.單位:n  
  10. -p size:設定管道緩衝區的最大值.單位:kbytes  
  11. -s size:設定堆疊的最大值.單位:kbytes  
  12. -t size:設定CPU使用時間的最大上限.單位:seconds  
  13. -v size:設定虛擬記憶體的最大值.單位:kbytes  
  14. unlimited 是一個特殊值,用於表示不限制  

ulimit命令的特點:

1.只對當前tty(終端有效),若要每次都生效的話,可以把ulimit引數放到對應使用者的.bash_profile裡面;
2.ulimit命令本身就有分軟硬設定,加-H就是硬,加-S就是軟;
硬限制是可以在任何時候任何程序中設定  但硬限制只能由超級使用者提起
軟限制是核心實際執行的限制,任何程序都可以將軟限制設定為任意小於等於對程序限制的硬限制的值
3.預設顯示的是軟限制,如果執行ulimit命令修改的時候沒有加上的話,就是兩個引數一起改變生效;

永久設定


針對所有使用者的設定,在/etc/security/limits.conf檔案,其是可以對系統使用者、組進行cpu、檔案數等限制的,通過它可以針對某個使用者或全部進行限制。但不能超越系統的限制;
格式:
#<domain>   <type> <item><value>
*           soft   noproc        102400


domain:表示範圍,
a user name       #表示某個使用者
a group name  #表示某個組
the wildcard *    #表示所有使用者
the wildcard %    #篩選過濾使用者


type:表示型別
soft表示可以超出,但只是警告
hard表示絕對不能超出


item:
- core - limits the core file size (KB)
- data - max data size (KB)
- fsize - maximum filesize (KB)
- memlock - max locked-in-memory address space (KB)
- nofile - max number of open file descriptors
- rss - max resident set size (KB)
- stack - max stack size (KB)
- cpu - max CPU time (MIN)
- nproc - max number of processes
- as - address space limit (KB)
- maxlogins - max number of logins for this user
- maxsyslogins - max number of logins on the system
- priority - the priority to run user process with
- locks - max number of file locks the user can hold
- sigpending - max number of pending signals
- msgqueue - max memory used by POSIX message queues (bytes)
- nice - max nice priority allowed to raise to values: [-20, 19]
- rtprio - max realtime priority


value:
unlimited表示不限制


如果想對所有使用者設定,也可以放在/etc/profile檔案裡面,下面是該檔案裡面的預設引數:
ulimit -S -c 0 > /dev/null 2>&1

--------------------------------------------------------------------------------------------------------------------------

有一臺伺服器訪問量非常高,使用的是nginx ,錯誤日誌不停報以下錯誤:

2016/05/16 08:53:49 [alert] 13576#0: accept() failed (24: Too many open files)
2016/05/16 08:53:49 [alert] 13576#0: accept() failed (24: Too many open files)
2016/05/16 08:53:49 [alert] 13576#0: accept() failed (24: Too many open files)
2016/05/16 08:53:49 [alert] 13576#0: accept() failed (24: Too many open files)
2016/05/16 08:53:49 [alert] 13576#0: accept() failed (24: Too many open files)
2016/05/16 08:53:49 [alert] 13576#0: accept() failed (24: Too many open files)
2016/05/16 08:53:49 [alert] 13576#0: accept() failed (24: Too many open files)
2016/05/16 08:53:49 [alert] 13576#0: accept() failed (24: Too many open files)
2016/05/16 08:53:49 [alert] 13576#0: accept() failed (24: Too many open files)
2016/05/16 08:53:49 [alert] 13576#0: accept() failed (24: Too many open files)

解決方法:

centos5.3 中 ulimit -n 為1024, 當Nginx連線數超過1024時,error.log中就出現以下錯誤:

[alert] 12766#0: accept() failed (24: Too many open files)

使用 ulimit -n 655350 可以把開啟檔案數設定足夠大, 同時修改nginx.conf , 新增 worker_rlimit_nofile 655350; (與error_log同級別)

這樣就可以解決Nginx連線過多的問題,Nginx就可以支援高併發。<還要修改nginx>

另外, ulimit -n 還會影響到mysql 的併發連線數。把他提高,也就提高了mysql併發。

注意: 用ulimit -n 2048 修改只對當前的shell有效,退出後失效。

修改方法

若要令修改ulimits的數值永久生效,則必須修改配置文件,可以給ulimit修改命令放入/etc/profile裡面,這個方法實在是不方便,

還有一個方法是修改/etc/security/limits.conf

/etc/security/limits.conf 格式,檔案裡面有很詳細的註釋,比如

* soft nofile 655360

* hard nofile 655360

星號代表全域性, soft為軟體,hard為硬體,nofile為這裡指可開啟檔案數。

把以上兩行內容加到 limits.conf檔案中即可。

另外,要使 limits.conf 檔案配置生效,必須要確保 pam_limits.so 檔案被加入到啟動檔案中。檢視 /etc/pam.d/login 檔案中有:

session required /lib/security/pam_limits.so

修改完重新登入就可以見到效果,可以通過 ulimit -n 檢視。