lsof命令是Liunx操作系統中對文件進行監控的一個常用命令,使用該命令可以列出當前系統打開了那些文件,系統中某個進程打開了那些文件等信息。
lsof命令必須在root下運行,因為lsof命令執行時候需要訪問核心內存和內核文件。
如下是直接運行使用lsof命令得到的一部分截圖數據,
第一列:展示了進程的名稱,
第二列:為進程ID
第四列:為進程的所有者
第五列:為文件描述符,cwd:為當前工作目錄。mem:表示把磁盤文件映射到內存中。txt:進程運行的程序文件,包括編譯后的代碼。rtd:表示root目錄。pd:表示父目錄。ltx:表示共享的lib數據。m86:合並映射文件。mmap:表示把磁盤設備映射到內存中。err:文件描述信息錯誤。tr:表示內核跟蹤文件。DEl:表示已經刪除的Liunx映射文件。數字+字符,如0u、1w、2w等,0表示標准輸出,1表示標准注入,2表示標准錯誤,u表示文件被打開,且處於讀取/寫入模式。r只讀模式,w表示打開且處於寫入模式。
第六列:為打開的文件類型,DIR 為目錄,CHR特殊字符文件,LINK 鏈接文件,IPv4 IPV4嵌套文件.IPv6打開了一根IPv6文件,REG 普通文件,FIFO先進先出的隊列文件。unix域套接字 通信方式。MPB 多路復用的塊文件。MPC 多路復用的字符文件。inet intet域套接字
第七列:設備號,已逗號分隔,
第八列:文件大小
第九列:操作系統本地文件的node number或者服務器主機中的NFS文件的inode unmber或者協議類型
第十列:文件的絕對路徑或者網絡通信鏈接的地址、端口,狀態或者掛載點等
lsof加參數
1、lsof -c:查看某個進程名稱當前打開了那些文件。
2、lsof -p: 查看某個進程ID當前打開了那些文件。
3、lsof -i: 查看IPv4 v6下打開的文件,此時看到的大部分是網絡鏈接通信,回包括服務段的Listen監聽或者客戶端和服務段的網絡通信。
冒號后面加端口時,可以定位到某個端口下v4 v6模式打開的文件和該端口的網絡鏈接通信。如上圖,可看到22端口下的網絡鏈接通信情況。可以看到22端口下有兩個監聽,一個是v4 另外一個是v6,都啟在了root用戶下,為tcp連接。
連接狀態如下
在TCP協議中又一個FLAGS 字段,這個字段 包含SYN(建立連接標識)、FIN(關閉連接標識)、ACK(響應確認標識)、PSH (DATA SS數據傳輸標識)、RST (連接重置標識)、URG(緊急標識)。但是不管什么樣子的TCP連接,都會占用服務器大量資源,且每一個連接都會占用一個端口,服務器TCP和UDP的端口總數只有65535個。超過這個范圍就會造成端口不夠用,應用程序就無法啟動,連接也無法進行,所以服務器出現大量的,CLOSE_WAIT 和TIME_WAIT的連接時,就需要及時的查找原因並進行優化,出現CLOSE_WAIT狀態,大多數是自己編寫的代碼或者應用程序出現了問題導致。
如果出現大量的TIME_WAIT狀態連接,可以從服務端進行一些優化,讓服務器更快的釋放TIME_WAIT狀態的連接所以占用的資源,可以參考如下方式進行優化。
a、通過/etc/sysctl.conf 文件,優化Linux操作系統的文件內核參數設置,在該文件中加入如下參數
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_max_tw_buckets = 5000
fs.file-max = 90000
net.ipv4.tcp_max_syn_backlog = 2000
net.core.somaxconn = 2048
net.ipv4.tcp_synack_retries = 1
net.ipv4.ip_local_port_range = 2048 65535
net.core.rmem_max = 2187154
net.core.wmem_max = 2187154
net.core.rmem_default = 250000
net.core.wmem_default = 250000
b、配置保存后,使用sysctl -p 命令讓配置立即生效,以上調優,在nginx、apache這種的web服務器經常用到
如下為各個參數的解釋
net.ipv4.tcp_syncookies = 1 表示開啟syn cookies,當出現syn等待隊列溢出的時,啟用cookies來處理,默認情況服務器是關閉該配置的。客戶端向Linux服務器建立TCP通信連接時會首先發送SYN包,發送完后, 客戶端會等待服務端SYN+ACK的回復,服務端給客戶端進行SYN+ACK的回復后,服務端此時會將處於SYN_RECV狀態的連接保存到半連接隊列中,以便等待客戶端繼續發送ACK 請求給服務端,直到連接最終完全建立,在出現大量的並發請求時候,這個半連接隊列里面就會緩存大量的SYN_RECV狀態的連接,從而導致隊列溢出,隊列的長度可以通過內核參數net.ipv4.tcp_max_syn_backlog 進行控制,在開啟cookies后服務端就不需要在將SYN_RECV保存到半連接隊列中,而是在回復SYN+ACK的時候,就將連接信息保存在ISN中返回給客戶端,當客戶端進行ACK請求時候,通過ISN來獲取連接信息,以完成最終的TCP協議通信。
net.ipv4.tcp_tw_reuse = 1 表示連接重用,即允許操作系統將TIME_WAIT socket的連接重新用於新的tcp連接請求,默認為關閉狀態。
net.ipv4.tcp_tw_recycle = 1 表示開啟操作系統中的TIME_WAIT socket連接狀態的快速回收,默認為關閉狀態。
net.ipv4.tcp_fin_timeout = 30 設置服務器主動關閉連接時,socket 連接保持等待狀態的最大時間。
net.ipv4.tcp_keepalive_time = 600 表示在請求開啟keepalive時, TCP發送keepalive消息的時間間隔,默認為7200秒,設置短一些可以更快速的清理掉無效的請求。
net.ipv4.tcp_max_tw_buckets = 5000 表示連接為TIME_WAIT狀態時,操作系統允許其他接收的套接字數量的最大值,過多的TIME_WAIT套接字會使web服務器變慢。
fs.file-max = 90000 表示操作系統可以同時打開的句柄數,在LINUX操作系統中,這個參數有時候會限制web服務器可以支持的最大連接數,這個參數是對貞干系統生效的。但是采用 ulimit -n 可以查看進程打開的最大句柄數,在句柄數不夠的時候,通常會報oo many open files的報錯。
net.ipv4.tcp_max_syn_backlog = 2000 表示服務器冷接受SYN同步包的最大客戶端連接數,也就是上面提到的半連接數的最大數量,默認值為128
net.core.somaxconn = 2048 表示服務器能處理的最大客戶端連接數,指的是能同時完成連接建立的最大數量,默認值為128
net.ipv4.tcp_synack_retries = 1 表示服務端在發送SYN+ACK后,在為未收到客戶端的ACK請求時,服務端重新嘗試發送SYN+ACK回復的重試次數。
net.ipv4.ip_local_port_range = 2048 65535 修改可以用於和客戶端建立連接的端口范圍,默認值配置的是32769 -61000,修改此參數是為了避免端口不夠用的情況。
net.core.rmem_max = 2187154 表示操作系統內核socket 接受緩沖區的最大值 單位為字節。
net.core.wmem_max = 2187154 表示操作系統內核socket 發送緩沖區的最大值 單位為字節。
net.core.rmem_default = 250000 表 示操作系統內核socket 接收緩沖區的默認值 單位為字節
net.core.wmem_default = 250000 表示操作系統內核socket 發送緩沖區的默認值 單位為字節
c、修改/etc/security/limits.conf文件,用於修改進程能夠打開的最大句柄數。
可增加如下配置
soft nofile 65535
hard nofile 65535
3、lsof +d 列出指定目錄下被使用的文件(當前路徑)
4、lsof +D 與+d類似,但是+D會 遞歸查找
5 、lsof 后面加指定文件,可以查看該文件被什么進程所使用
6 、lsof -i:@ip 可以列出指定ip的所有網絡通信連接