回覆列表
  • 1 # 爻信社交

    問題有一個概念上的誤解,錯誤的把TCP埠號的上限65535理解成了TCP連線數的上限,進而認為Linux無法實現超過65,535個的併發任務,實際上埠號數量和TCP連線數確實有關聯,但並非一一對應的關係。

    65,535從哪來的,幹啥的?

    要解釋好這個問題,就要先說清楚65,535的含義。

    在Linux系統中,如果兩個機器要通訊,那麼相互之間需要建立TCP連線,為了讓雙方互相認識,Linux系統用一個四元組來唯一標識一個TCP連線: {local ip, local port, remote ip, remote port},即本機IP、本機埠、遠端IP、遠端埠,IP和埠就相當於小區地址和門牌號,只有拿到這些資訊,通訊的雙方才能互相認知。

    在Linux系統中,表示埠號(port)的變數佔16位,這就決定了埠號最多有2的16次方個,即65,536個,另外埠0有特殊含義不給使用,這樣每個伺服器最多就有65,535個埠可用。因此,65,535代表Linux系統支援的TCP埠號數量,在TCP建立連線時會使用。

    TCP怎麼建立連線,與埠號是什麼關係?

    (1)伺服器端主動建立監聽的socket,並繫結對外服務埠port,然後開始監聽

    (2)客戶端想跟伺服器端通訊時,就開始連線伺服器的埠port

    (3)服務端接受客戶端的請求,然後再生成新的socket

    (4)伺服器和客戶端在新的socket裡進行通訊

    可以看到,埠port主要用在伺服器和客戶端的“握手認識”過程,一旦互相認識了,就會生成的的socket進行通訊,這時候port就不再需要了,可以給別的socket通訊去使用,所以很明顯TCP連線的數量可以大於TCP埠號的數量65,535。

    考慮一下兩個極端場景,即某臺Linux伺服器只作為客戶端或者伺服器端

    (1)Linux伺服器只作為客戶端

    這時候每發起一個TCP請求,系統就會指定一個空間的本地埠給你用,而且是獨佔式的,不會被別的TCP連線搶走,這樣最多可以建立65535個連線,每個連線都與不同的伺服器進行互動。這種場景,就是題主所描述的樣子,但是由於條件過於苛刻,屬於小概率事件,所以更多的還是理論上的可能,現實的環境中幾乎不會出現。

    (2)Linux伺服器只作為服務端

    這種場景下,服務端就會固定的監聽本地埠port,等著客戶端來向它發起請求。為了計算簡單,我們假設伺服器端的IP跟埠是多對一的,這樣TCP四元組裡面就有remote ip和remote port是可變的,因此最大支援建立TCP個數為2的32次方(IP地址是32位的)乘以2的16次方(port是16位的)等於2的48次方。

    現實中單臺Linux伺服器支援的TCP連線數量

    通過前面的分析我們知道,在現實場景中,由於存在埠port複用的情況,伺服器可同時支援的TCP連線數跟65,535沒有一一對應關係,事實上,真正影響TCP連線數量的,是伺服器的記憶體以及允許單一程序同時開啟檔案的數量,因為每建立一個TCP連線都要建立一個socket控制代碼,每個socket控制代碼都佔用一部分系統記憶體,當系統記憶體被佔用殆盡,允許的TCP併發連線數也就到了上限。

    一般來講,通過增加伺服器記憶體、修改最大檔案描述符個數等,可以做到單臺伺服器支援10萬+的TCP併發

    當然,在真實的商用場景下,單臺伺服器都會編入分散式叢集,通過負載均衡演算法動態的排程不同使用者的請求給最空閒的伺服器,如果伺服器平均記憶體使用超過80%的警戒線,那麼就會及時採用限流或者擴充套件叢集的方式來保證服務,絕對不會出現伺服器的記憶體被耗盡的情況,那樣就算事故了。

    總之,65,535只是Linux系統中可使用埠port數量的上限,埠port數量與TCP連線數量並非完全一一對應的關係,伺服器支援的TCP併發連線數量主要跟伺服器的記憶體以及允許單個程序同時開啟的檔案數量有關係,通過埠複用及調整伺服器引數等手段,單臺伺服器支援的TCP併發連線數是可以高於65,535的。

  • 2 # 老邢聊科技

    下面我結合之前的專案來回答一下。

    樓主所理解的65535(埠數量)與連線數是一個東西,這個是錯的。具體原因前面已經有不少同行小夥伴描述的非常清楚了,我就不再闡述了。

    下面我具體來回答一下樓主的後半部分:伺服器是如何支撐百萬併發的。

    下面闡述的觀點是:通過優化系統架構提升系統負載能力,即提高系統併發量。

    一、什麼是高併發

    高併發是網際網路系統所面臨的普通問題,也是系統架構時考慮的重要因素之一。

    併發與負載】是相對的兩個詞。

    想實現高併發,就要提高系統負載能力。系統負載能力強了,自然可以處理高併發請求。

    所以,實現高併發,本質就是提高系統的負載能力。

    一般對於系統負載能力的評估引數有:響應時間 、吞吐量、每秒請求數QPS、併發使用者數。

    響應時間:系統對請求做出響應的時間。例如系統處理一個HTTP請求需要200ms,這個200ms就是系統的響應時間。吞吐量:單位時間內處理的請求數量。QPS:每秒響應請求數,與吞吐量概念類似。併發使用者數:同時使用系統功能的使用者數量。二、如何提高併發處理能力(併發數)

    需要說明的是:以下內容不考慮【頻寬】和【硬體配置】這兩個因素。

    很顯然,頻寬高、硬體配置高,系統負載能力就強,能處理的併發使用者數就多。

    那麼如何提高併發處理能力呢?

    答案就是:通過優化系統架構來提高併發處理能力。

    並且系統架構設計是一個複雜的過程,不僅涉及到技術層面,還包括業務層面。

    三、通過業務拆分提高併發處理能力(微服務架構)

    將一個系統拆分為多個子系統,每個子系統負責一個單獨的服務,這就是常說的【服務治理】

    拆分為多個子系統後,每個子系統(服務)獨立執行,每個服務之間通過REST/RPC方式呼叫,使用者也可以直接呼叫這些服務介面。

    這種設計將大化小,這種架構也稱為【微服務架構】。

    舉例:商城系統中,可拆分為【訂單服務】【使用者服務】【產品服務】等多個服務介面。

    四、通過水平擴充套件提高併發處理能力

    這一塊要分開來講。

    1. 前端部分

    使用nginx反向代理軟體提高併發處理量

    nginx進行水平擴充套件:DNS輪詢等

    2. 應用伺服器部分

    java中常見的應用伺服器tomcat為例,它可以實現叢集和負載均衡。叢集配置成功後,相當於提供了一個“伺服器池”,如果想要再提高處理能力,只需要向“池”中繼續新增應用伺服器即可。另外,叢集也實現了系統高可用。

    3. 資料庫層面

    常見的分庫分表,讀寫分離都是解決資料庫壓力大的方法之一。

    資料庫瓶頸是系統在執行中最先碰到、最常碰到的問題之一。

    經常見到的問題就是磁碟IO高,導致處理緩慢。

    剛才所說方法都可以解決這一問題。

    常見的分表原則有:按範圍分,按雜湊值分。

    4. 快取層面

    在系統中新增快取是當前必選的方案。

    新增快取的主要目標是減少磁碟IO。

    可以快取的內容很多,例如快取頁面內容(HTML,CSS,圖片),快取應用伺服器中資料物件等。

    通過設計多級快取,實現資料的快速獲取、請求的快速響應。

    在分散式架構中,還要注意分散式快取的更新一致性問題。(不再詳述)

    五、最後

    其實很多系統的併發數都不到百萬級,只有少量頭部網站才會有,例如淘寶。

    但我們之所以研究如何解決百萬級併發架構,是從中學會和掌握【系統架構演變過程】

    系統架構設計的原則是:適合的就是最好的。不能剛開始架構就要滿足百萬級,因為這樣設計會提高成本,造成資源浪費。

    所以,我們要明白:系統架構是演進的。

    只有當我們經歷了從【單一架構】至【分散式架構】這一過程,才能真正理解架構的能力。在這過程中,你的架構能力也會飛快增長。

    我是一名Java全棧開發工程師、系統架構師,從業15年。曾帶領小團隊完成多個數百萬級專案。我正在寫一些關於網際網路行業及開發技術方面的文章。關注我,你一定會有所收穫。

  • 3 # dttsw

    我看了10幾個回答沒有一個是完全對的。TCP連線分兩種。

    前面網友說的大多是客戶端連線或TCP客戶端連線。一臺計算機上能使用的埠確實只有65535。在linux上遵循unix標準,客戶端連線是從1W多還是2W多開始的,這我記不清,其它被保留了或者註冊。

    如果要用保留埠,也可以連線時指定埠,非系統管理員賬號能用1024後端口,1024前埠只有系統管理員可用。是指執行程式使用者身份。

    所以從這角度說linuxTCP客戶端連線與監聽埠絕對不超過65535。

    如現在的服務式應用,客戶端呼叫可以保留長連結,佔用埠不會很多。隨機選等釋放埠。

    上面說的是單網路介面。因為埠+IP可以標識唯一應用或者請求,因此,如果有多個網路介面,就是網絡卡,限制又可以擴展出來。

    對服務端TCP連線,這個絕對有上限,linux上可調。會被以下幾個引數影響:

    1、程序可開啟的檔案描述符限制,可調,傳統unix這個值一般是1024;

    2、設定監聽套接字時有一個backlog值,設定大了也可以增加連線數;

    3、linux系統裡有兩個核心引數與backlog相關,這兩引數名稱記不住,但一定可調。跟backlog一起影響連線數上限。

    2、3兩種情況驟可以單獨設定,會對TCP服務端連線數產生影響。

    backlog值與核心引數的關係,有人看核心原始碼也沒完全搞清具體關係,再具體點系統可能會根據負載能力調整,設定多少不一定能連線那麼多。也就是沒確切值。

    服務端的TCP連線在作業系統核心中至少保留兩個佇列,已連線指完成三次捂手的連結,未連線等待三次捂手的連線。

    知道上面理論,再來考慮併發。理論上可以把服務端連線調整得很大。但考慮幾個問題,太大的連結佇列,作業系統做排程效率多少回有影響。如果機器負載不行,已連線佇列但是使用者程序未處理的多,說明機器或應用處理速度不行。因此單程序即便調也得調整個合理值。

    服務端連線佇列,伺服器對程序維護或者可對程序維護,考慮到併發一定設計多程序負載均衡問題。多程序分單機與多機。實際高併發應用,兩種方式都會有而且是結合使用。

    具體根據實際情況設計,距列,nginx單機多程序應用。微服務,一般多機多程序應用。nginx多機多程序與單機多程序配合工作就變成叢集。

  • 4 # 十三相會

    tcp的最大連線數當然可以超過65535

    65535有兩個意思:一是Linux系統使用者最大開啟檔案限制

    檢視Linux系統對同時開啟檔案數的硬限制:

    # sysctl -a|grep file-max

    fs.file-max = 65535

    這表明這臺Linux系統最多允許同時開啟(即包含所有使用者開啟檔案數總和)65535個檔案,是Linux系統級硬限制,所有使用者級的開啟檔案數限制都不會超過這個數值。

    通常這個系統級硬限制是Linux系統在啟動時根據系統硬體資源狀況計算出來的最佳的最大同時開啟檔案數限制。

    二是伺服器網路埠最大的埠號。

    在單機Linux中,一個埠能夠接受tcp連結數量的理論上限是65535 * 65535

    對於百萬,千萬的併發,可以採用多程序之間的負載均衡,如果單臺負載機不夠的話 就用多機負載方案

  • 5 # 日說月曰

    tcp包有源地址和埠號 服務端用這兩個組合標識對方 源地址是4byte 理論上2的32次方大大超過65535. 所以可接入百萬以上 當然前提系統開啟檔案數目 頻寬 cpu等因素要保證

  • 6 # 我在雲南農村

    首先澄清一下65535是埠的限制並不是連結數!

    其次:一個埠可以有好幾十上百的連結!

    所以,只要效能足夠,百萬併發是可以達到的!

  • 7 # 2評論

    服務端好多人說了,略過不表,但真多人對客戶端TCP上限理解有誤。

    其實,客戶端TCP連線數量,可簡單突破埠65535的限制。

    方法:為客戶端網絡卡配個IP,每個IP都有65535(扣掉知名埠),盡情地去日伺服器吧。

  • 8 # 特立不雞群

    關鍵點就是多IP,一臺伺服器可以有很多IP,可以多網絡卡多IP,也可以單網絡卡多IP,這樣做一下負載均衡,就可以了!

  • 9 # 北嗅

    65536是埠數,也就是 client 的最大數,作為客戶端根據配置還有一些埠不能使用(一般認為是前1024),服務端的決定於檔案描述符的數量,理論上是沒有上限的,決定於系統核心的配置。

  • 10 # sun34457526

    一個伺服器是不可能響應上百萬的使用者的,物理上肯定是伺服器群,雙十一,12306這種肯定是幾十萬臺的規模才行。

  • 中秋節和大豐收的關聯?
  • 華為mate30,6+128版本怎麼樣?