nginx端口占用案例分享

這裏分享一個案例,問題的原因是反向代理使用不當。

現象

首先描述一下問題的現象。當時的問題是應用啓動失敗,日誌裏面報錯顯示端口占用。我們的應用都是通過腳本發佈的,之前發佈過多次都沒有出現過問題。那麼同樣的腳本、同樣的機器,這次怎麼就發佈失敗了呢?

報錯信息如下:

OSError: [Errno 48] Address already in use

問題排查

這個報錯是很常見的,以爲是發佈的過程中上一個應用沒有正常關閉。然後熟練的打開終端,連接到服務器,通過netstat -ant|grep LISTEN命令檢查這個端口被誰佔用了。這條命令的輸出如下:

tcp        0      0 0.0.0.0:53130          0.0.0.0:*              LISTEN

tcp        0      0 0.0.0.0:39308          0.0.0.0:*              LISTEN

tcp        0      0 0.0.0.0:111            0.0.0.0:*              LISTEN

tcp        0      0 0.0.0.0:22              0.0.0.0:*              LISTEN

tcp        0      0 0.0.0.0:46429          0.0.0.0:*              LISTEN

tcp        0      0 0.0.0.0:2049            0.0.0.0:*              LISTEN

tcp        0      0 0.0.0.0:51329          0.0.0.0:*              LISTEN

tcp6      0      0 0.0.0.0:2280            :::*                    LISTEN

我們的服務使用8080端口。於是熟練的在輸出的內容裏尋找8080。可是並沒有找到!

看來這次情況跟以往不太一樣了。怎麼會這樣呢?既然沒有端口占用,爲什麼應用會起不來?於是我再次嘗試啓動應用,還是報了相同的錯誤。

轉機

既然這樣,那麼我直接搜索8080試試,於是輸入了下面的命令:

netstat -ant | grep 8080

很快,得到了下面的結果:

tcp        0      0 192.168.6.55:59580        192.168.6.55:8080    TIME_WAIT

居然出現了TIME_WAIT。在我的三觀裏TIME_WAIT只會出現在斷開連接的時候啊,監聽端口是不會出現TIME_WAIT的。這是要打破三觀的節奏嗎?

真相

真相只有一個。我讓運維借用sudo權限看看這個連接是哪個進程的。最後發現這個端口是被nginx佔用的。原來,nginx接收了很多請求,進行代理的時候發起tcp連接,這時會佔用一個未被使用的隨機端口。而後端應用和nginx部署在同一臺機器,由於請求過多,nginx發起了大量連接,每個連接都是短連接,佔用了大量的隨機端口,並且需要經過30秒的TIME_WAIT狀態才能釋放佔用。碰巧把後端應用的8080端口也佔用了,導致應用無法啓動。

結論

不要把nginx和後端應用部署在同一臺機器。會有一定機率導致後端應用的端口被佔用。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章