公司的一臺服務器升級,原先運行正常的一個服務經常會跳出,于是予以分析解決。
該服務是一個tcp的服務端程序,被動接收客戶端連接處理數據,升級后當客戶端連接到一定量后程序會自動跳出。
使用netstat查看各個狀態的數量
netstat -na |awk ‘{print $6}’|sort |uniq -c |sort -nr
發現很多的CLOSE_WAIT,并且還在不斷增加中。
覺得可能是CLOSE_WAIT得不到釋放,占用很多資源,
于是修改sysctl.conf中關于tcp連接的連接時間等設置,結果問題依舊。
懷疑收到攻擊,使用
netstat -na |grep CLOSE_WAIT|awk ‘{print $5}’|awk -F”:” ‘{print $1}’|sort |uniq -c |sort -nr |wc -l 查看連接過來的地址,發現都是地址來源都是正常的
首先檢查
使用 ps -fe |grep programname 查看獲得進程的pid
再使用 ps -Lf pid 查看對應進程下的線程數,發現數值為303,遠小于實際應該的數量。于是初步判斷是由于線程數不夠造成的原因。查找資料發現可以通過設置 ulimit -s 來增加每進程線程數。
每進程可用線程數 = VIRT上限/stack size
其中 VIRT 上限: 32位x86 = 3G 64位x64=64G
statck size 默認是 10240 因此在默認情況下
32位系統上單進程最多可以創建300個線程,
64系統在內存充足的情況下最多可以創建 6400 個線程。
在機器硬件固定的情況下,可以通過 ulimit -s 降低stack size 的設置值來獲得更多的每進程線程數。