Linux服務器報錯too many open files錯誤解決方案


1、本質解決方案按照oracle的安裝腳本中以下幾項文件進行相應配置:

cp /etc/security/limits.conf /etc/security/limits.conf.bak

echo "oracle soft nproc 2047" >>/etc/security/limits.conf

echo "oracle hard nproc 16384" >>/etc/security/limits.conf

echo "oracle soft nofile 1024" >>/etc/security/limits.conf

echo "oracle hard nofile 65536" >>/etc/security/limits.conf

cp /etc/pam.d/login /etc/pam.d/login.bak

echo "session required /lib/security/pam_limits.so" >>/etc/pam.d/login

echo "session required pam_limits.so" >>/etc/pam.d/login

cp /etc/profile /etc/profile.bak

echo 'if [ $USER = "oracle" ]; then' >>  /etc/profile

echo 'if [ $SHELL = "/bin/ksh" ]; then' >> /etc/profile

echo 'ulimit -p 16384' >> /etc/profile

echo 'ulimit -n 65536' >> /etc/profile

echo 'else' >> /etc/profile

echo 'ulimit -u 16384 -n 65536' >> /etc/profile

echo 'fi' >> /etc/profile

echo 'fi' >> /etc/profile

cp /etc/sysctl.conf /etc/sysctl.conf.bak

echo "fs.aio-max-nr = 1048576" >> /etc/sysctl.conf

echo "fs.file-max = 6815744" >> /etc/sysctl.conf

echo "kernel.shmall = 2097152" >> /etc/sysctl.conf

echo "kernel.shmmax = 4294967295" >> /etc/sysctl.conf

echo "kernel.shmmni = 4096" >> /etc/sysctl.conf

echo "kernel.sem = 250 32000 100 128" >> /etc/sysctl.conf

echo "net.ipv4.ip_local_port_range = 9000 65500" >> /etc/sysctl.conf

echo "net.core.rmem_default = 262144" >> /etc/sysctl.conf

echo "net.core.rmem_max = 4194304" >> /etc/sysctl.conf

echo "net.core.wmem_default = 262144" >> /etc/sysctl.conf

echo "net.core.wmem_max = 1048586" >> /etc/sysctl.conf

echo "net.ipv4.tcp_wmem = 262144 262144 262144" >> /etc/sysctl.conf

echo "net.ipv4.tcp_rmem = 4194304 4194304 4194304" >> /etc/sysctl.conf

sysctl -p

2、臨時解決方案:

[root@zytest04 ~]# ulimit -a

core file size          (blocks, -c) 0

data seg size           (kbytes, -d) unlimited

scheduling priority             (-e) 0

file size               (blocks, -f) unlimited

pending signals                 (-i) 46418

max locked memory       (kbytes, -l) 64

max memory size         (kbytes, -m) unlimited

open files                      (-n) 1024

pipe size            (512 bytes, -p) 8

POSIX message queues     (bytes, -q) 819200

real-time priority              (-r) 0

stack size              (kbytes, -s) 10240

cpu time               (seconds, -t) unlimited

max user processes              (-u) 46418

virtual memory          (kbytes, -v) unlimited

file locks                      (-x) unlimited

[root@zytest04 ~]# ulimit -n 4096

[root@zytest04 ~]# ulimit -a

core file size          (blocks, -c) 0

data seg size           (kbytes, -d) unlimited

scheduling priority             (-e) 0

file size               (blocks, -f) unlimited

pending signals                 (-i) 46418

max locked memory       (kbytes, -l) 64

max memory size         (kbytes, -m) unlimited

open files                      (-n) 4096

pipe size            (512 bytes, -p) 8

POSIX message queues     (bytes, -q) 819200

real-time priority              (-r) 0

stack size              (kbytes, -s) 10240

cpu time               (seconds, -t) unlimited

max user processes              (-u) 46418

virtual memory          (kbytes, -v) unlimited

file locks                      (-x) unlimited

3、轉自網絡文檔

第一部分:(主要是命令,查看最大打開限制數量,不能解決根本問題)

在Linux下,我們使用ulimit -n 命令可以看到單個進程能夠打開的最大文件句柄數量(socket連接也算在里面)。系統默認值1024。

對於一般的應用來說(象Apache、系統進程)1024完全足夠使用。但是如何象squid、mysql、java等單進程處理大量請求的應用來說就有點捉襟見肘了。如果單個進程打開的文件句柄數量超過了系統定義的值,就會提到“too many files open”的錯誤提示。如何知道當前進程打開了多少個文件句柄呢?下面一段小腳本可以幫你查看:

00001. lsof -n |awk '{print $2}'|sort|uniq -c |sort -nr|more   

在系統訪問高峰時間以root用戶執行上面的腳本,可能出現的結果如下:

00001. # lsof -n|awk '{print $2}'|sort|uniq -c |sort -nr|more   

00002.     131 24204  

00003.      57 24244  

00004.      57 24231  

00005.      56 24264  

其中第一行是打開的文件句柄數量,第二行是進程號。得到進程號后,我們可以通過ps命令得到進程的詳細內容。

00001. ps -aef|grep 24204  

00002. mysql    24204 24162 99 16:15 ?        00:24:25 /usr/sbin/mysqld  

哦,原來是mysql進程打開最多文件句柄數量。但是他目前只打開了131個文件句柄數量,遠遠底於系統默認值1024。

但是如果系統並發特別大,尤其是squid服務器,很有可能會超過1024。這時候就必須要調整系統參數,以適應應用變化。Linux有硬性限制和軟性限制。可以通過ulimit來設定這兩個參數。方法如下,以root用戶運行以下命令:

00001. ulimit -HSn 4096  

以上命令中,H指定了硬性大小,S指定了軟性大小,n表示設定單個進程最大的打開文件句柄數量。個人覺得最好不要超過4096,畢竟打開的文件句柄數越多響應時間肯定會越慢。設定句柄數量后,系統重啟后,又會恢復默認值。如果想永久保存下來,可以修改.bash_profile文件,可以修改 /etc/profile 把上面命令加到最后。(findsun提出的辦法比較合理)

=================================================================================

Too many open files經常在使用linux的時候出現,大多數情況是您的程序沒有正常關閉一些資源引起的,所以出現這種情況,請檢查io讀寫,socket通訊等是否正常關閉。
如果檢查程序沒有問題,那就有可能是linux默認的open files值太小,不能滿足當前程序默認值的要求,比如數據庫連接池的個數,tomcat請求連接的個數等。。。
查看當前系統open files的默認值,可執行:

Java代碼 wps5BC6.tmp

00001. [root@pororo script]# ulimit -a   

00002. core file size           (blocks, -c) 0

00003. data seg size            (kbytes, -d) unlimited   

00004. scheduling priority              (-e) 0

00005. file size                (blocks, -f) unlimited   

00006. pending signals                  (-i) 128161

00007. max locked memory        (kbytes, -l) 32

00008. max memory size          (kbytes, -m) unlimited   

00009. open files                       (-n) 800000

00010. pipe size             (512 bytes, -p) 8

00011. POSIX message queues      (bytes, -q) 819200

00012. real-time priority               (-r) 0

00013. stack size               (kbytes, -s) 10240

00014. cpu time                (seconds, -t) unlimited   

00015. max user processes               (-u) 128161

00016. virtual memory           (kbytes, -v) unlimited   

00017. file locks                       (-x) unlimited  

00018. ==========================================================================

00019. 第二部分:(解決的真正方法)

功能說明:控制shell程序的資源。

語  法:ulimit [-aHS][-c <core文件上限>][-d <數據節區大小>][-f <文件大 小>][-m <內存大小>][-n <文件數目>][-p <緩沖區大小>][-s <堆疊大 小>][-t <CPU時間>][-u <程序數目>][-v <虛擬內存大小>]

補充說明:ulimit為shell內建指令,可用來控制shell執行程序的資源。

參  數:
-a  顯示目前資源限制的設定。
-c <core文件上限>  設定core文件的最大值,單位為區塊。
-d <數據節區大小>  程序數據節區的最大值,單位為KB。
-f <文件大小>  shell所能建立的最大文件,單位為區塊。
-H  設定資源的硬性限制,也就是管理員所設下的限制。
-m <內存大小>  指定可使用內存的上限,單位為KB。
-n <文件數目>  指定同一時間最多可開啟的文件數。
-p <緩沖區大小>  指定管道緩沖區的大小,單位512字節。
-s <堆疊大小>  指定堆疊的上限,單位為KB。
-S  設定資源的彈性限制。
-t <CPU時間>  指定CPU使用時間的上限,單位為秒。
-u <程序數目>  用戶最多可開啟的程序數目。
-v <虛擬內存大小>  指定可使用的虛擬內存上限,單位為KB。

ulimit -a 用來顯示當前的各種用戶進程限制。
    Linux對於每個用戶,系統限制其最大進程數。為提高性能,可以根據設備資源情況,
    設置各linux 用戶的最大進程數,下面我把某linux用戶的最大進程數設為10000個:
     ulimit -u 10000
     對於需要做許多 socket 連接並使它們處於打開狀態的 Java 應用程序而言,
     最好通過使用 ulimit -n xx 修改每個進程可打開的文件數,缺省值是 1024。
     ulimit -n 4096 將每個進程可以打開的文件數目加大到4096,缺省為1024
     其他建議設置成無限制(unlimited)的一些重要設置是:
     數據段長度:ulimit -d unlimited
     最大內存大小:ulimit -m unlimited
     堆棧大小:ulimit -s unlimited
     CPU 時間:ulimit -t unlimited
     虛擬內存:ulimit -v unlimited
我們公司服務器需要調整ulimit的stack size 參數調整為unlimited 無限,使用ulimit -s unlimited時只能在當時的shell見效,重開一個shell就失效了。。於是得在/etc/profile 的最后面添加ulimit -s unlimited 就可以了,source /etc/profile使修改文件生效。
PS:如果你碰到類似的錯誤提示
ulimit: max user processes: cannot modify limit: 不允許的操作
ulimit: open files: cannot modify limit: 不允許的操作
為啥root用戶是可以的?普通用戶又會遇到這樣的問題?
看一下/etc/security/limits.conf大概就會明白。
linux對用戶有默認的ulimit限制,而這個文件可以配置用戶的硬配置和軟配置,硬配置是個上限。
超出上限的修改就會出“不允許的操作”這樣的錯誤。
在limits.conf加上
*        soft    noproc  10240
*        hard    noproc  10240
*        soft    nofile  10240
*        hard    nofile  10240
就是限制了任意用戶的最大線程數和文件數為10240。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM