今天客戶物理機上遇到檔案描述符用盡的問題,現象包括:
ssh連線物理機卡住
pg服務埠tcp心跳檢測失敗
psql卡住
報錯:too many open files
在linux系統中一切皆可以看成是檔案,檔案又可分為:普通檔案、目錄檔案、鏈結檔案和裝置檔案。
檔案描述符(file descriptor)是核心為了高效管理已被開啟的檔案所建立的索引,其是乙個非負整數(通常是小整數),用於指代被開啟的檔案,所有執行i/o操作的系統呼叫都通過檔案描述符。
程式剛剛啟動的時候,0是標準輸入,1是標準輸出,2是標準錯誤。如果此時去開啟乙個新的檔案,它的檔案描述符會是3。posix標準要求每次開啟檔案時(含socket)必須使用當前程序中最小可用的檔案描述符號碼,因此,在網路通訊過程中稍不注意就有可能造成串話。標準檔案描述符圖如下:
檔案描述與開啟的檔案對應模型如下圖:
在編寫檔案操作的或者網路通訊的軟體時,初學者一般可能會遇到too many open files
的問題。這主要是因為檔案描述符是系統的乙個重要資源,雖然說系統記憶體有多少就可以開啟多少的檔案描述符,但是在實際實現過程中核心是會做相應的處理的,一般最大開啟檔案數會是系統記憶體的10%(以kb來計算)(稱之為系統級限制),檢視系統級別的最大開啟檔案數可以使用sysctl -a | grep fs.file-max
命令檢視。與此同時,核心為了不讓某乙個程序消耗掉所有的檔案資源,其也會對單個程序最大開啟檔案數做預設值處理(稱之為使用者級限制),預設值一般是1024,使用ulimit -n命令可以檢視。
確認當前值
確認當前檔案描述符數量
# -w忽略告警
lsof -w | wc -l
192987
watch "lsof -w | wc -l"
檢視某程序的檔案描述符數量
lsof -p pid | wc -l
排序檢視當前程序開啟了多少控制代碼數
lsof -wn|awk ''|sort|uniq -c|sort -nr|more
系統級引數配置
系統所有程序一共可以開啟的檔案數量,
file-max是設定系統所有程序一共可以開啟的檔案數量
cat /proc/sys/fs/file-max
6553600
sysctl -a | grep file-max
fs.file-max = 6553600
# 修改
echo 6553560 > /proc/sys/fs/file-max
# 或修改 /etc/sysctl.conf, 加入
fs.file-max = 6553560
sysctl -p
>> 使用者級引數配置vi /etc/security/limits.conf
* soft nofile 102400
* hard nofile 102400
mingjie.gmj soft nofile 75535
mingjie.gmj hard nofile 75535
shell級引數配置
linux限制每個登入使用者的可連線檔案數。可通過ulimit -n來檢視當前有效設定。如果想修改這個值就使用 ulimit -n 命令。
ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 4133861
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 65535
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) 4133861
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
具體情況要具體分析,要理解具體其概況如何,需要檢視由核心維護的3個資料結構。
程序級的檔案描述符表
程序級的描述符表的每一條目記錄了單個檔案描述符的相關資訊。
系統級的開啟檔案描述符表
核心對所有開啟的檔案的檔案維護有乙個系統級的描述符**(open file description table)。有時,也稱之為開啟檔案表(open file table),並將**中各條目稱為開啟檔案控制代碼(open file handle)。乙個開啟檔案控制代碼儲存了與乙個開啟檔案相關的全部資訊,如下所示:
檔案系統的i-node表
下圖展示了檔案描述符、開啟的檔案控制代碼以及i-node之間的關係,圖中,兩個程序擁有諸多開啟的檔案描述符。
檔案描述符 file descriptor
核心 kernel 利用檔案描述符 file descriptor 來訪問檔案。檔案描述符是非負整數。開啟現存盤案或新建檔案時,核心會返回乙個檔案描述符。讀寫檔案也需要使用檔案描述符來指定待讀寫的檔案。1簡介 2特點2.1 優點2.2 缺點 3 定義數量 4解決方法 檔案描述符在形式上是乙個非負整數...
小金問呀問不會問題
problem description 眾所周知,c語言的學習是我們程式設計基礎的重點和主要內容。小金在班裡是乙個愛學習的好孩子,但是他的程式設計能力卻有點差,不過他堅信自己一定可以進步並追上其他同學。input 多組輸入。從鍵盤讀入乙個整數n,如果n 0代表小金考試進步了,如果n 0代表小金退步了...
小金問呀問不會問題
problem description 眾所周知,c語言的學習是我們程式設計基礎的重點和主要內容。小金在班裡是乙個愛學習的好孩子,但是他的程式設計能力卻有點差,不過他堅信自己一定可以進步並追上其他同學。input 多組輸入。從鍵盤讀入乙個整數n,如果n 0代表小金考試進步了,如果n 0代表小金退步了...