File Descriptor問題總結

2021-09-19 10:06:40 字數 3153 閱讀 2971

今天客戶物理機上遇到檔案描述符用盡的問題,現象包括:

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代表小金退步了...