不知道你有沒有遇到過這種問題:在同一臺物理機器上,服務a 啟動時偵聽 埠1 ,同時它也作為客戶端去連線 服務b,連線服務b時候會隨機乙個埠號,假如隨機的是 埠2 ,這個時候 服務c 正在啟動中,它發現需要偵聽的埠號已經被 服務a的隨機埠 ( 埠號2 ) 占用了,導致服務c 啟動失敗
上述的問題是 伺服器 偵聽的埠 被客戶端隨機的埠給占用掉了,導致伺服器無法啟動,接下來將介紹 這種情況出現的原因以及如何解決該問題
要弄清楚問題的原因,先需要了解下系統是如何隨機埠號的
linux 下/proc/sys/net/ipv4/ip_local_port_range
定義了本地埠的範圍,此檔案有兩個整形引數,分別表示本地最小埠號和最大埠號
客戶端呼叫connect
函式連線伺服器的時候,作業系統會從本地埠範圍中隨機乙個沒有使用的埠,作為本次連線的源埠號,如果沒有可用的隨機埠,則連線出錯
在早期的 linux 版本中,本地埠範圍是從1024
到5000
,總共有 3976 個埠可用,隨著網路應用的不斷增多,併發連線也會達到新的量級,埠範圍可能會不夠用,所以,新的 linux 版本調整了本地埠的範圍
下面是在linux 3.10
下檢視的結果
[root@cghost22 ~]# cat /proc/sys/net/ipv4/ip_local_port_range
32768 61000
注意:1024 以下的埠是系統保留埠,如果想修改 ip_local_port_range 中的埠, 確保都要大於1024
通過對隨機埠的了解以及對問題的分析,有以下幾種解決方案
前面提到,服務a 作為客戶端先連線 服務b,客戶端隨機的源埠 和 服務c 的偵聽埠重複了,導致 服務c 偵聽失敗
如果是這樣,那麼調整下服務啟動順序,讓 服務c 在 服務a 之前啟動,這樣就能保證 服務c 先偵聽埠,後面 服務a 再隨機埠就不會和 服務c 的偵聽埠 重複了
讓 某些服務 需要先於另一些 服務 啟動,會增加 服務 之間的耦合度,在設計中需要盡量避免這麼做
退一步說,即使這麼做了,如果後面 服務c 重啟,在它重啟的過程中,服務a 恰好正在重新連線 服務b, 此時還是有可能出現 服務a 隨機的埠 和 服務c 的 偵聽埠重複,當該埠 先被 服務a 使用了,那麼 服務c 還是會偵聽失敗的
從上面 隨機埠 小節可知,偵聽埠 和 隨機埠出現重複的原因是 偵聽埠剛好處於 隨機埠的範圍中,所以隨機埠才有機率出現和偵聽埠相同
只要修改下 偵聽埠 ,使之不會出現在 隨機埠範圍中,比如:把隨機埠範圍設定為32768-61000
,再把偵聽埠設定為1024-32767
之間的乙個值, 這樣隨機埠 和 偵聽埠 就不會出現重複了
如此做確實能解決問題,但是 修改 服務 的偵聽埠,跟該 服務 有邏輯關係上下游都需要做相應的調整,如果專案已經上線了,還需要走一套發布更新流程,需要花費不少時間,如果專案還在開發中,可以直接修改偵聽埠
這種方法是將 偵聽埠 新增到 本地保留埠列表中,系統在隨機埠的時候,會過濾掉本地保留埠列表中配置的埠號, 服務只需要做任何改動,只需要重啟下埠重複了的兩個 服務 即可
本地保留埠的配置位於/proc/sys/net/ipv4/ip_local_reserved_ports
, 它支援埠範圍以及單個埠號的配置,單個埠號之間用逗號分隔,埠範圍的最小值和最大值之間用"-"符號分隔
例如:50001,5200-5300,6001
表示 本地保留的是 5001,5200 到 5300,6001 這些埠
不過,如果直接配置/proc/sys/net/ipv4/ip_local_reserved_ports
檔案的話,重啟機器之後配置會失效,要想重啟機器依然生效,直接配置/etc/sysctl.conf
下面是配置本地保留的5001,5200 到 5300,6001
埠的例項
用vim
編輯/etc/sysctl.conf
,在檔案末尾新增以下行
net.ipv4.ip_local_reserved_ports=5001,5200-5300,6001
再執行sysctl -p
命令過載/etc/sysctl.conf
配置
本文介紹了 linux 下隨機埠和偵聽埠重複的原因以及解決方法,雖然可以通過設定本地保留埠來解決,但這畢竟需要多一步配置操作,而且如果服務遷移到其他機器或者當前機器上有服務使用新的偵聽埠,還得新增到本地保留埠中,所以,這種方法比較適合線上緊急處理,比較推薦的做法還是修改下偵聽埠,確保偵聽埠不在隨機埠範圍內
linux下解決80埠被占用
重灌nginx服務,在啟動的時候報80埠被占用了 首先我們查一下占用80埠的有哪些服務,netstat lnp grep 80 檢視80埠被那些服務占用。我們會發現其實就是nginx自己占用了80埠,重灌的時候只是刪除了nginx檔案,並沒有關閉nginx,所以出現這種情況,服務名稱前面是他的pid...
linux下解決80埠被占用
安裝乙個nginx服務,在啟動的時候報80埠被占用了,我們來檢查一下有哪些服務占用了80埠 首先我們查一下占用80埠的有哪些服務,netstat lnp grep 80 檢視80埠被那些服務占用。會發現其實就是第一行httpd服務占用了80埠,服務名稱前面是他的pid號 可以看到httpd服務占用了...
linux 檢視埠被占用
linux 檢視埠被占用 linux 檢視埠被占用 1 lsof i 埠號 用於檢視某一埠的占用情況,比如檢視8080埠使用情況,lsof i 8080 如果執行 lsof i 8080 系統提示 bash lsof 未找到命令,則要安裝lsof 使用 yum install lsof 如下圖 安裝...