最近在項目中遇到一個很奇怪的問題,因為修改配置(redis中緩存的)摩瞎,nginx服務突然報upstream timed out (110: Connection timed out),然后去查為什么會出現(xiàn)這樣的問題,發(fā)現(xiàn)出問題的服務是一個golang的http server,查看程序日志贮竟,發(fā)現(xiàn)大量的accept4: too many open files報錯,第一感覺應該是哪里文件句柄讀取沒有釋放较剃。
too many open files(打開的文件過多)是Linux系統(tǒng)中常見的錯誤咕别,從字面意思上看就是說程序打開的文件數(shù)過多,不過這里的files不單是文件的意思重付,也包括打開的通訊鏈接(比如socket)顷级,正在監(jiān)聽的端口等等凫乖,所以有時候也可以叫做句柄(handle)确垫,這個錯誤通常也可以叫做句柄數(shù)超出系統(tǒng)限制。 引起的原因就是進程在某個時刻打開了超過系統(tǒng)限制的文件數(shù)量以及通訊鏈接數(shù)帽芽。
1. 查看系統(tǒng)的配置 ulimit -a | grep open删掀,發(fā)現(xiàn)系統(tǒng)的配置正常。
2. 查看程序服務的打開文件限制导街,cat /proc/40636/limits披泪,發(fā)現(xiàn)服務的限制并沒有繼承系統(tǒng)設置的,還是系統(tǒng)默認的1024限制搬瑰。
3. 查看程序服務打開文件數(shù)(連接數(shù))情況款票,lsof -p 40636 | wc -l控硼,發(fā)現(xiàn)已經(jīng)超出限制,所以報錯艾少。
4. 再看看程序服務打開了哪些連接卡乾,lsof -p 40636 > openfiles.log,發(fā)現(xiàn)很多http連接打開沒有關閉缚够,看ip是報警服務的接口幔妨,于是順著這條線索,終于找到了原因谍椅,因為程序中讀取到的配置解析時報錯給報警服務误堡,大量的報警服務連接后未關閉,才導致的too many open files雏吭,這是問題的關鍵锁施,但是程序為什么沒有繼承系統(tǒng)設置的最大配置限制,還需要繼續(xù)查看杖们。
5. 最終原因找到沾谜,因為程序服務是supervisor管理的,supervisor啟動服務默認的minfds配置是1024胀莹,也就是打開文件限制是1024基跑,在supervisor的配置中加入minfds=81920; 重啟supervisorctl reload,再次查看程序進程文件限制描焰,正常了媳否,困擾我一上午的問題終于解決,大呼“爽”荆秦。