{eval=Array;=+count(Array);}
舉個例子:
我們做了一個網站,綁定的是TCP的80端口,結果是所有訪問這個網站的用戶都是通過服務器的80端口訪問,而不是其他端口。可見端口是可以復用的。即使Linux服務器只在80端口偵聽服務, 也允許有10萬、100萬個用戶連接服務器。Linux系統不會限制連接數至于服務器能不能承受住這么多的連接,取決于服務器的硬件配置、軟件架構及優(yōu)化。
我們知道兩個進程如果需要進行通訊最基本的一個前提是:能夠唯一的標示一個進程。在本地進程通訊中我們可以使用PID來唯一標示一個進程,但PID只在本地唯一,網絡中的兩個進程PID沖突幾率很大。
這時候就需要另辟它徑了,IP地址可以唯一標示主機,而TCP層協議和端口號可以唯一標示主機的一個進程,這樣可以利用IP地址+協議+端口號唯一標示網絡中的一個進程。
能夠唯一標示網絡中的進程后,它們就可以利用socket進行通信了。socket(套接字)是在應用層和傳輸層之間的一個抽象層,它把TCP/IP層復雜的操作抽象為幾個簡單的接口供應用層調用已實現進程在網絡中通信。socket源自Unix,是一種"打開—讀/寫—關閉"模式的實現,服務器和客戶端各自維護一個"文件",在建立連接打開后,可以向自己文件寫入內容供對方讀取或者讀取對方內容,通訊結束時關閉文件。
唯一能夠確定一個連接有4個東西:
1. 服務器的IP
2. 服務器的Port
3. 客戶端的IP
4. 客戶端的Port
服務器的IP和Port可以保持不變,只要客戶端的IP和Port彼此不同就可以確定一個連接數。一個socket是可以建立多個連接的,一個TCP連接的標記為一個四元組(source_ip, source_port, destination_ip, destination_port),即(源IP,源端口,目的IP,目的端口)四個元素的組合。只要四個元素的組合中有一個元素不一樣,那就可以區(qū)別不同的連接。
舉個例子:
->你的主機IP地址是1.1.1.1, 在8080端口監(jiān)聽
->當一個來自 2.2.2.2 發(fā)來一條連接請求,端口為5555。這條連接的四元組為(1.1.1.1, 8080, 2.2.2.2, 5555)
->這時2.2.2.2又發(fā)來第二條連接請求,端口為6666。新連接的四元組為(1.1.1.1, 8080, 2.2.2.2, 6666)
那么,你主機的8080端口建立了兩條連接;
->(2.2.2.2)發(fā)來的第三條連接請求,端口為5555(或6666)。第三條連接的請求就無法建立,因為沒有辦法區(qū)分于上面兩條連接。
同理,可以在同一個端口號和IP地址上綁定一個TCP socket和一個UDP socket
因為端口號雖然一樣,但由于協議不一樣,所以端口是完全獨立的。
TCP/UDP一般采用五元組來定位一個連接:
source_ip, source_port, destination_ip, destination_port, protocol_type
即(源IP,源端口,目的IP,目的端口,協議號)
所以也就能理解淘寶、ucloud、我們、百度、新浪、嗶嗶嗶嗶等為什么能夠承受住每秒種幾億次的并發(fā)訪問,是因為他們采用的是服務器集群。服務器集群分布在全國各地的大型機房,當訪問量小的時候會關閉一些服務器,當訪問量大的時候回不斷的開啟新的服務器。
以上個人淺見,歡迎批評指正。
認同我的看法,請點個贊再走,感謝!
喜歡我的,請關注我,再次感謝!
首先,問題中描述的65535個連接指的是客戶端連接數的限制。
在tcp應用中,server事先在某個固定端口監(jiān)聽,client主動發(fā)起連接,經過三路握手后建立tcp連接。那么對單機,其最大并發(fā)tcp連接數是多少呢?
在確定最大連接數之前,先來看看系統如何標識一個tcp連接。系統用一個4四元組來唯一標識一個TCP連接:{localip, localport,remoteip,remoteport}。
client每次發(fā)起tcp連接請求時,除非綁定端口,通常會讓系統選取一個空閑的本地端口(local port),該端口是獨占的,不能和其他tcp連接共享。tcp端口的數據類型是unsigned short,因此本地端口個數最大只有65536,端口0有特殊含義,不能使用,這樣可用端口最多只有65535,所以在全部作為client端的情況下,一個client最大tcp連接數為65535,這些連接可以連到不同的serverip。
server通常固定在某個本地端口上監(jiān)聽,等待client的連接請求。不考慮地址重用(unix的SO_REUSEADDR選項)的情況下,即使server端有多個ip,本地監(jiān)聽端口也是獨占的,因此server端tcp連接4元組中只有remoteip(也就是clientip)和remote port(客戶端port)是可變的,因此最大tcp連接為客戶端ip數×客戶端port數,對IPV4,不考慮ip地址分類等因素,最大tcp連接數約為2的32次方(ip數)×2的16次方(port數),也就是server端單機最大tcp連接數約為2的48次方。
上面給出的是理論上的單機最大連接數,在實際環(huán)境中,受到機器資源、操作系統等的限制,特別是sever端,其最大并發(fā)tcp連接數遠不能達到理論上限。在unix/linux下限制連接數的主要因素是內存和允許的文件描述符個數(每個tcp連接都要占用一定內存,每個socket就是一個文件描述符),另外1024以下的端口通常為保留端口。
所以,對server端,通過增加內存、修改最大文件描述符個數等參數,單機最大并發(fā)TCP連接數超過10萬,甚至上百萬是沒問題的。
你這個提問中有一些邏輯的錯誤,我來一一給你解釋一下。
第一個錯誤的地方是,TCP連接數量和Linux沒有關系。不管是Windows還是Linux,只要使用TCP/IP,那么單個IP地址連接相同互聯網服務的TCP連接數,就不會超過65535個,甚至在一般情況下,我們認為不會超過4萬個(注意,這里指相同互聯網服務,即相同目的地址和端口)。
這個原因是因為,TCP/IP中,一個TCP連接,就要耗費源IP地址一個TCP端口,而TCP的端口數量也就是65535個,因為協議規(guī)定了TCP端口的長度也就是16位(二進制),所以換成十進制也就是1~65535.
這也就意味著,如果你的電腦要訪問一個網站,那么你的電腦只能和這個網站建立65535個連接,一個連接消耗一個TCP端口。當然這是理想的情況,實際的情況是,有很多端口被一些知名的協議占據了,或者做了預留,例如80端口就屬于HTTP的,所以一般認為能使用的端口就是4萬個左右。
第二個錯誤是,TCP的端口數量和服務器沒有關系。因為這里所說的4萬個TCP的端口,是指源端口,也就是你訪問網站時使用的個人電腦使用的端口,而對于目的端口,也就是網站的端口,使用的TCP端口也就是相同的23端口。這個意思也就意味著,4萬個連接都連的是這個網站的23端口,換一個用戶又可以用4萬個連接連接服務器的23端口。
所以我們可以粗略估算一下,如果是100萬個并發(fā)連接,在1個用戶4萬個訪問的情況下,也就是25個并發(fā)的用戶。當然,實際使用時,你的PC機不會有4萬個連接訪問相同的網站,假設我們按照一個PC機4個連接訪問網站計算,100萬個并發(fā)也就是25萬個用戶訪問。
最后回答一下你的問題,服務器如何撐住百萬千萬個TCP連接呢?這個和服務器的資源有關。實際上單個服務器支持的TCP連接數的確是有限的,單個服務器所支持的TCP連接不可能到達理論值,服務連接一多,CPU撐不住內存也頂不住,所以每個服務器都有規(guī)格限制,硬件性能越強,服務器支持的TCP連接數越大。
但是一個網站可以有多個服務器啊,可以有集群服務器啊,服務器的規(guī)模越大,支持的訪問能力就越強,所以這個也不是問題。
比如ucloud巴巴是如何撐過雙11的?ucloud云在北上廣深等很多地方都有服務器,而且每個地方的服務器都是彈性集群,這些服務器實時同步保障淘寶上的數據一致。所以雙11訪問淘寶時,有的訪問的是北京的服務器,有的訪問的是上海的服務器,這樣通過分布式服務分布式的存儲,網站可以應對的并發(fā)自然就很大了。
Hi,你好。很高興看到并回答此問題。如果我的回答對你有幫助,記得點個贊哦~~
下面我結合之前的項目來回答一下。
樓主所理解的65535(端口數量)與連接數是一個東西,這個是錯的。具體原因前面已經有不少同行小伙伴描述的非常清楚了,我就不再闡述了。
下面我具體來回答一下樓主的后半部分:服務器是如何支撐百萬并發(fā)的。
下面闡述的觀點是:通過優(yōu)化系統架構提升系統負載能力,即提高系統并發(fā)量。
高并發(fā)是互聯網系統所面臨的普通問題,也是系統架構時考慮的重要因素之一。
【并發(fā)與負載】是相對的兩個詞。
想實現高并發(fā),就要提高系統負載能力。系統負載能力強了,自然可以處理高并發(fā)請求。
所以,實現高并發(fā),本質就是提高系統的負載能力。
一般對于系統負載能力的評估參數有:響應時間 、吞吐量、每秒請求數QPS、并發(fā)用戶數。
需要說明的是:以下內容不考慮【帶寬】和【硬件配置】這兩個因素。
很顯然,帶寬高、硬件配置高,系統負載能力就強,能處理的并發(fā)用戶數就多。
那么如何提高并發(fā)處理能力呢?
答案就是:通過優(yōu)化系統架構來提高并發(fā)處理能力。
并且系統架構設計是一個復雜的過程,不僅涉及到技術層面,還包括業(yè)務層面。
將一個系統拆分為多個子系統,每個子系統負責一個多帶帶的服務,這就是常說的【服務治理】
拆分為多個子系統后,每個子系統(服務)獨立運行,每個服務之間通過REST/RPC方式調用,用戶也可以直接調用這些服務接口。
這種設計將大化小,這種架構也稱為【微服務架構】。
舉例:商城系統中,可拆分為【訂單服務】【用戶服務】【產品服務】等多個服務接口。
這一塊要分開來講。
1. 前端部分
使用nginx反向代理軟件提高并發(fā)處理量
nginx進行水平擴展:DNS輪詢等
2. 應用服務器部分
java中常見的應用服務器tomcat為例,它可以實現集群和負載均衡。集群配置成功后,相當于提供了一個“服務器池”,如果想要再提高處理能力,只需要向“池”中繼續(xù)添加應用服務器即可。另外,集群也實現了系統高可用。
3. 數據庫層面
常見的分庫分表,讀寫分離都是解決數據庫壓力大的方法之一。
數據庫瓶頸是系統在運行中最先碰到、最常碰到的問題之一。
經常見到的問題就是磁盤IO高,導致處理緩慢。
剛才所說方法都可以解決這一問題。
常見的分表原則有:按范圍分,按哈希值分。
4. 緩存層面
在系統中添加緩存是當前必選的方案。
添加緩存的主要目標是減少磁盤IO。
可以緩存的內容很多,例如緩存頁面內容(HTML,CSS,圖片),緩存應用服務器中數據對象等。
通過設計多級緩存,實現數據的快速獲取、請求的快速響應。
在分布式架構中,還要注意分布式緩存的更新一致性問題。(不再詳述)
其實很多系統的并發(fā)數都不到百萬級,只有少量頭部網站才會有,例如淘寶。
但我們之所以研究如何解決百萬級并發(fā)架構,是從中學會和掌握【系統架構演變過程】。
系統架構設計的原則是:適合的就是最好的。不能剛開始架構就要滿足百萬級,因為這樣設計會提高成本,造成資源浪費。
所以,我們要明白:系統架構是演進的。
只有當我們經歷了從【單一架構】至【分布式架構】這一過程,才能真正理解架構的能力。在這過程中,你的架構能力也會飛快增長。
我是一名Java全棧開發(fā)工程師、系統架構師,從業(yè)15年。曾帶領小團隊完成多個數百萬級項目。我正在寫一些關于互聯網行業(yè)及開發(fā)技術方面的文章。關注我,你一定會有所收獲。
如果有項目開發(fā)、行業(yè)及求職方面的問題,都可以在評論區(qū)留言或私信我。(關注后私信我,向你免費分享行業(yè)級學習資料)
你好,IT行業(yè)的碼農前來答題。
題主有一個概念上的誤解,錯誤的把TCP端口號的上限65535理解成了TCP連接數的上限,進而認為Linux無法實現超過65,535個的并發(fā)任務,實際上端口號數量和TCP連接數確實有關聯,但并非一一對應的關系。
要解釋好這個問題,就要先說清楚65,535的含義。在Linux系統中,如果兩個機器要通信,那么相互之間需要建立TCP連接,為了讓雙方互相認識,Linux系統用一個四元組來唯一標識一個TCP連接: {local ip, local port, remote ip, remote port},即本機IP、本機端口、遠程IP、遠程端口,IP和端口就相當于小區(qū)地址和門牌號,只有拿到這些信息,通信的雙方才能互相認知。在Linux系統中,表示端口號(port)的變量占16位,這就決定了端口號最多有2的16次方個,即65,536個,另外端口0有特殊含義不給使用,這樣每個服務器最多就有65,535個端口可用。因此,65,535代表Linux系統支持的TCP端口號數量,在TCP建立連接時會使用。
Linux服務器在交互時,一般有兩種身份:客戶端或者服務器端。典型的交互場景是:
(1)服務器端主動創(chuàng)建監(jiān)聽的socket,并綁定對外服務端口port,然后開始監(jiān)聽
(2)客戶端想跟服務器端通信時,就開始連接服務器的端口port
(3)服務端接受客戶端的請求,然后再生成新的socket
(4)服務器和客戶端在新的socket里進行通信
可以看到,端口port主要用在服務器和客戶端的“握手認識”過程,一旦互相認識了,就會生成的的socket進行通信,這時候port就不再需要了,可以給別的socket通信去使用,所以很明顯TCP連接的數量可以大于TCP端口號的數量65,535。
(1)Linux服務器只作為客戶端
這時候每發(fā)起一個TCP請求,系統就會指定一個空間的本地端口給你用,而且是獨占式的,不會被別的TCP連接搶走,這樣最多可以建立65535個連接,每個連接都與不同的服務器進行交互。這種場景,就是題主所描述的樣子,但是由于條件過于苛刻,屬于小概率事件,所以更多的還是理論上的可能,現實的環(huán)境中幾乎不會出現。
(2)Linux服務器只作為服務端
這種場景下,服務端就會固定的監(jiān)聽本地端口port,等著客戶端來向它發(fā)起請求。為了計算簡單,我們假設服務器端的IP跟端口是多對一的,這樣TCP四元組里面就有remote ip和remote port是可變的,因此最大支持創(chuàng)建TCP個數為2的32次方(IP地址是32位的)乘以2的16次方(port是16位的)等于2的48次方。
通過前面的分析我們知道,在現實場景中,由于存在端口port復用的情況,服務器可同時支持的TCP連接數跟65,535沒有一一對應關系,事實上,真正影響TCP連接數量的,是服務器的內存以及允許單一進程同時打開文件的數量,因為每創(chuàng)建一個TCP連接都要創(chuàng)建一個socket句柄,每個socket句柄都占用一部分系統內存,當系統內存被占用殆盡,允許的TCP并發(fā)連接數也就到了上限。一般來講,通過增加服務器內存、修改最大文件描述符個數等,可以做到單臺服務器支持10萬+的TCP并發(fā)。
當然,在真實的商用場景下,單臺服務器都會編入分布式集群,通過負載均衡算法動態(tài)的調度不同用戶的請求給最空閑的服務器,如果服務器平均內存使用超過80%的警戒線,那么就會及時采用限流或者擴展集群的方式來保證服務,絕對不會出現服務器的內存被耗盡的情況,那樣就算事故了。
總之,65,535只是Linux系統中可使用端口port數量的上限,端口port數量與TCP連接數量并非完全一一對應的關系,服務器支持的TCP并發(fā)連接數量主要跟服務器的內存以及允許單個進程同時打開的文件數量有關系,通過端口復用及調整服務器參數等手段,單臺服務器支持的TCP并發(fā)連接數是可以高于65,535的。
TCP/IP 協議規(guī)定了端口數占兩個字節(jié),所以 65535 是端口數的上限,但是和連接數不是一個意思。
一個 TCP 連接(會話)用四元組來標識:
客戶端IP : 源端口 -> 服務器 IP : 目的端口
TCP 連接大概有這么幾種場景:
1,服務端需要監(jiān)聽特定的端口(socket listen),比如 WEB 需要監(jiān)聽 80 和 8080 端口,監(jiān)聽的端口是獨占的,也就是說同一 IP 的端口綁定數量上限是 65535;
2,客戶端連接服務器,系統會自動分配本地空閑端口,本地端口也是獨占的,所以傳出連接數(Outgoing)上限是 65535;
3,當服務端收到傳入的連接請求(socket accept)并建立連接,對于服務端而言,傳入連接并不會產生新的端口占用,連接數量不受端口限制,而是操作系統和系統資源限制。
首先,問題中描述的65535個連接指的是客戶端連接數的限制。
在tcp應用中,server事先在某個固定端口監(jiān)聽,client主動發(fā)起連接,經過三路握手后建立tcp連接。那么對單機,其最大并發(fā)tcp連接數是多少呢?
如何標識一個TCP連接
在確定最大連接數之前,先來看看系統如何標識一個tcp連接。系統用一個4四元組來唯一標識一個TCP連接:{localip, localport,remoteip,remoteport}。
client最大tcp連接數
client每次發(fā)起tcp連接請求時,除非綁定端口,通常會讓系統選取一個空閑的本地端口(local port),該端口是獨占的,不能和其他tcp連接共享。tcp端口的數據類型是unsigned short,因此本地端口個數最大只有65536,端口0有特殊含義,不能使用,這樣可用端口最多只有65535,所以在全部作為client端的情況下,一個client最大tcp連接數為65535,這些連接可以連到不同的serverip。
server最大tcp連接數
server通常固定在某個本地端口上監(jiān)聽,等待client的連接請求。不考慮地址重用(unix的SO_REUSEADDR選項)的情況下,即使server端有多個ip,本地監(jiān)聽端口也是獨占的,因此server端tcp連接4元組中只有remoteip(也就是clientip)和remote port(客戶端port)是可變的,因此最大tcp連接為客戶端ip數×客戶端port數,對IPV4,不考慮ip地址分類等因素,最大tcp連接數約為2的32次方(ip數)×2的16次方(port數),也就是server端單機最大tcp連接數約為2的48次方。
實際的tcp連接數
上面給出的是理論上的單機最大連接數,在實際環(huán)境中,受到機器資源、操作系統等的限制,特別是sever端,其最大并發(fā)tcp連接數遠不能達到理論上限。在unix/linux下限制連接數的主要因素是內存和允許的文件描述符個數(每個tcp連接都要占用一定內存,每個socket就是一個文件描述符),另外1024以下的端口通常為保留端口。
所以,對server端,通過增加內存、修改最大文件描述符個數等參數,單機最大并發(fā)TCP連接數超過10萬,甚至上百萬是沒問題的。
這明顯是進入了思維的誤區(qū),65535是指可用的端口總數,并不代表服務器同時只能接受65535個并發(fā)連接。
舉個例子:
我們做了一個網站,綁定的是TCP的80端口,結果是所有訪問這個網站的用戶都是通過服務器的80端口訪問,而不是其他端口。可見端口是可以復用的。即使Linux服務器只在80端口偵聽服務, 也允許有10萬、100萬個用戶連接服務器。Linux系統不會限制連接數至于服務器能不能承受住這么多的連接,取決于服務器的硬件配置、軟件架構及優(yōu)化。
01
我們知道兩個進程如果需要進行通訊最基本的一個前提是:能夠唯一的標示一個進程。在本地進程通訊中我們可以使用PID來唯一標示一個進程,但PID只在本地唯一,網絡中的兩個進程PID沖突幾率很大。
這時候就需要另辟它徑了,IP地址可以唯一標示主機,而TCP層協議和端口號可以唯一標示主機的一個進程,這樣可以利用IP地址+協議+端口號唯一標示網絡中的一個進程。
能夠唯一標示網絡中的進程后,它們就可以利用socket進行通信了。socket(套接字)是在應用層和傳輸層之間的一個抽象層,它把TCP/IP層復雜的操作抽象為幾個簡單的接口供應用層調用已實現進程在網絡中通信。socket源自Unix,是一種"打開—讀/寫—關閉"模式的實現,服務器和客戶端各自維護一個"文件",在建立連接打開后,可以向自己文件寫入內容供對方讀取或者讀取對方內容,通訊結束時關閉文件。
02
唯一能夠確定一個連接有4個東西:
1. 服務器的IP
2. 服務器的Port
3. 客戶端的IP
4. 客戶端的Port
服務器的IP和Port可以保持不變,只要客戶端的IP和Port彼此不同就可以確定一個連接數。一個socket是可以建立多個連接的,一個TCP連接的標記為一個四元組(source_ip, source_port, destination_ip, destination_port),即(源IP,源端口,目的IP,目的端口)四個元素的組合。只要四個元素的組合中有一個元素不一樣,那就可以區(qū)別不同的連接。
舉個例子:
->你的主機IP地址是1.1.1.1, 在8080端口監(jiān)聽
->當一個來自 2.2.2.2 發(fā)來一條連接請求,端口為5555。這條連接的四元組為(1.1.1.1, 8080, 2.2.2.2, 5555)
->這時2.2.2.2又發(fā)來第二條連接請求,端口為6666。新連接的四元組為(1.1.1.1, 8080, 2.2.2.2, 6666)
那么,你主機的8080端口建立了兩條連接;
->(2.2.2.2)發(fā)來的第三條連接請求,端口為5555(或6666)。第三條連接的請求就無法建立,因為沒有辦法區(qū)分于上面兩條連接。
同理,可以在同一個端口號和IP地址上綁定一個TCP socket和一個UDP socket
因為端口號雖然一樣,但由于協議不一樣,所以端口是完全獨立的。
TCP/UDP一般采用五元組來定位一個連接:
source_ip, source_port, destination_ip, destination_port, protocol_type
即(源IP,源端口,目的IP,目的端口,協議號)
綜上所述,服務器的并發(fā)數并不是由TCP的65535個端口決定的。服務器同時能夠承受的并發(fā)數是由帶寬、硬件、程序設計等多方面因素決定的。
所以也就能理解淘寶、ucloud、我們、百度、新浪、嗶嗶嗶嗶等為什么能夠承受住每秒種幾億次的并發(fā)訪問,是因為他們采用的是服務器集群。服務器集群分布在全國各地的大型機房,當訪問量小的時候會關閉一些服務器,當訪問量大的時候回不斷的開啟新的服務器。
以上個人淺見,歡迎批評指正。
認同我的看法,請點個贊再走,感謝!
你這個提問中有一些邏輯的錯誤,我來一一給你解釋一下。
第一個錯誤的地方是,TCP連接數量和Linux沒有關系。不管是Windows還是Linux,只要使用TCP/IP,那么單個IP地址連接相同互聯網服務的TCP連接數,就不會超過65535個,甚至在一般情況下,我們認為不會超過4萬個(注意,這里指相同互聯網服務,即相同目的地址和端口)。
這個原因是因為,TCP/IP中,一個TCP連接,就要耗費源IP地址一個TCP端口,而TCP的端口數量也就是65535個,因為協議規(guī)定了TCP端口的長度也就是16位(二進制),所以換成十進制也就是1~65535.
這也就意味著,如果你的電腦要訪問一個網站,那么你的電腦只能和這個網站建立65535個連接,一個連接消耗一個TCP端口。當然這是理想的情況,實際的情況是,有很多端口被一些知名的協議占據了,或者做了預留,例如80端口就屬于HTTP的,所以一般認為能使用的端口就是4萬個左右。
第二個錯誤是,TCP的端口數量和服務器沒有關系。因為這里所說的4萬個TCP的端口,是指源端口,也就是你訪問網站時使用的個人電腦使用的端口,而對于目的端口,也就是網站的端口,使用的TCP端口也就是相同的23端口。這個意思也就意味著,4萬個連接都連的是這個網站的23端口,換一個用戶又可以用4萬個連接連接服務器的23端口。
所以我們可以粗略估算一下,如果是100萬個并發(fā)連接,在1個用戶4萬個訪問的情況下,也就是25個并發(fā)的用戶。當然,實際使用時,你的PC機不會有4萬個連接訪問相同的網站,假設我們按照一個PC機4個連接訪問網站計算,100萬個并發(fā)也就是25萬個用戶訪問。
最后回答一下你的問題,服務器如何撐住百萬千萬個TCP連接呢?這個和服務器的資源有關。實際上單個服務器支持的TCP連接數的確是有限的,單個服務器所支持的TCP連接不可能到達理論值,服務連接一多,CPU撐不住內存也頂不住,所以每個服務器都有規(guī)格限制,硬件性能越強,服務器支持的TCP連接數越大。
但是一個網站可以有多個服務器啊,可以有集群服務器啊,服務器的規(guī)模越大,支持的訪問能力就越強,所以這個也不是問題。
比如ucloud巴巴是如何撐過雙11的?ucloud云在北上廣深等很多地方都有服務器,而且每個地方的服務器都是彈性集群,這些服務器實時同步保障淘寶上的數據一致。所以雙11訪問淘寶時,有的訪問的是北京的服務器,有的訪問的是上海的服務器,這樣通過分布式服務分布式的存儲,網站可以應對的并發(fā)自然就很大了。
樓主所理解的65535(端口數量)與連接數是一個東西,這個是錯的。具體原因前面已經有不少同行小伙伴描述的非常清楚了,我就不再闡述了。
下面我具體來回答一下樓主的后半部分:服務器是如何支撐百萬并發(fā)的。
下面闡述的觀點是:通過優(yōu)化系統架構提升系統負載能力,即提高系統并發(fā)量。
一、什么是高并發(fā)
高并發(fā)是互聯網系統所面臨的普通問題,也是系統架構時考慮的重要因素之一。
【并發(fā)與負載】是相對的兩個詞。
想實現高并發(fā),就要提高系統負載能力。系統負載能力強了,自然可以處理高并發(fā)請求。
所以,實現高并發(fā),本質就是提高系統的負載能力。
一般對于系統負載能力的評估參數有:響應時間 、吞吐量、每秒請求數QPS、并發(fā)用戶數。
響應時間:系統對請求做出響應的時間。例如系統處理一個HTTP請求需要200ms,這個200ms就是系統的響應時間。
吞吐量:單位時間內處理的請求數量。
QPS:每秒響應請求數,與吞吐量概念類似。
并發(fā)用戶數:同時使用系統功能的用戶數量。
二、如何提高并發(fā)處理能力(并發(fā)數)
需要說明的是:以下內容不考慮【帶寬】和【硬件配置】這兩個因素。
很顯然,帶寬高、硬件配置高,系統負載能力就強,能處理的并發(fā)用戶數就多。
那么如何提高并發(fā)處理能力呢?
答案就是:通過優(yōu)化系統架構來提高并發(fā)處理能力。
并且系統架構設計是一個復雜的過程,不僅涉及到技術層面,還包括業(yè)務層面。
三、通過業(yè)務拆分提高并發(fā)處理能力(微服務架構)
將一個系統拆分為多個子系統,每個子系統負責一個多帶帶的服務,這就是常說的【服務治理】
拆分為多個子系統后,每個子系統(服務)獨立運行,每個服務之間通過REST/RPC方式調用,用戶也可以直接調用這些服務接口。
這種設計將大化小,這種架構也稱為【微服務架構】。
舉例:商城系統中,可拆分為【訂單服務】【用戶服務】【產品服務】等多個服務接口。
四、通過水平擴展提高并發(fā)處理能力
這一塊要分開來講。
1. 前端部分
使用nginx反向代理軟件提高并發(fā)處理量
nginx進行水平擴展:DNS輪詢等
2. 應用服務器部分
java中常見的應用服務器tomcat為例,它可以實現集群和負載均衡。集群配置成功后,相當于提供了一個“服務器池”,如果想要再提高處理能力,只需要向“池”中繼續(xù)添加應用服務器即可。另外,集群也實現了系統高可用。
3. 數據庫層面
常見的分庫分表,讀寫分離都是解決數據庫壓力大的方法之一。
數據庫瓶頸是系統在運行中最先碰到、最常碰到的問題之一。
經常見到的問題就是磁盤IO高,導致處理緩慢。
剛才所說方法都可以解決這一問題。
常見的分表原則有:按范圍分,按哈希值分。
4. 緩存層面
在系統中添加緩存是當前必選的方案。
添加緩存的主要目標是減少磁盤IO。
可以緩存的內容很多,例如緩存頁面內容(HTML,CSS,圖片),緩存應用服務器中數據對象等。
通過設計多級緩存,實現數據的快速獲取、請求的快速響應。
在分布式架構中,還要注意分布式緩存的更新一致性問題。(不再詳述)
五、最后
其實很多系統的并發(fā)數都不到百萬級,只有少量頭部網站才會有,例如淘寶。
但我們之所以研究如何解決百萬級并發(fā)架構,是從中學會和掌握【系統架構演變過程】。
系統架構設計的原則是:適合的就是最好的。不能剛開始架構就要滿足百萬級,因為這樣設計會提高成本,造成資源浪費。
所以,我們要明白:系統架構是演進的。
題主有一個概念上的誤解,錯誤的把TCP端口號的上限65535理解成了TCP連接數的上限,進而認為Linux無法實現超過65,535個的并發(fā)任務,實際上端口號數量和TCP連接數確實有關聯,但并非一一對應的關系。
65,535從哪來的,干啥的?
要解釋好這個問題,就要先說清楚65,535的含義。在Linux系統中,如果兩個機器要通信,那么相互之間需要建立TCP連接,為了讓雙方互相認識,Linux系統用一個四元組來唯一標識一個TCP連接: {local ip, local port, remote ip, remote port},即本機IP、本機端口、遠程IP、遠程端口,IP和端口就相當于小區(qū)地址和門牌號,只有拿到這些信息,通信的雙方才能互相認知。在Linux系統中,表示端口號(port)的變量占16位,這就決定了端口號最多有2的16次方個,即65,536個,另外端口0有特殊含義不給使用,這樣每個服務器最多就有65,535個端口可用。因此,65,535代表Linux系統支持的TCP端口號數量,在TCP建立連接時會使用。
TCP怎么建立連接,與端口號是什么關系?
Linux服務器在交互時,一般有兩種身份:客戶端或者服務器端。典型的交互場景是:
(1)服務器端主動創(chuàng)建監(jiān)聽的socket,并綁定對外服務端口port,然后開始監(jiān)聽
(2)客戶端想跟服務器端通信時,就開始連接服務器的端口port
(3)服務端接受客戶端的請求,然后再生成新的socket
(4)服務器和客戶端在新的socket里進行通信
可以看到,端口port主要用在服務器和客戶端的“握手認識”過程,一旦互相認識了,就會生成的的socket進行通信,這時候port就不再需要了,可以給別的socket通信去使用,所以很明顯TCP連接的數量可以大于TCP端口號的數量65,535。
考慮一下兩個極端場景,即某臺Linux服務器只作為客戶端或者服務器端
(1)Linux服務器只作為客戶端
這時候每發(fā)起一個TCP請求,系統就會指定一個空間的本地端口給你用,而且是獨占式的,不會被別的TCP連接搶走,這樣最多可以建立65535個連接,每個連接都與不同的服務器進行交互。這種場景,就是題主所描述的樣子,但是由于條件過于苛刻,屬于小概率事件,所以更多的還是理論上的可能,現實的環(huán)境中幾乎不會出現。
(2)Linux服務器只作為服務端
這種場景下,服務端就會固定的監(jiān)聽本地端口port,等著客戶端來向它發(fā)起請求。為了計算簡單,我們假設服務器端的IP跟端口是多對一的,這樣TCP四元組里面就有remote ip和remote port是可變的,因此最大支持創(chuàng)建TCP個數為2的32次方(IP地址是32位的)乘以2的16次方(port是16位的)等于2的48次方。
現實中單臺Linux服務器支持的TCP連接數量
通過前面的分析我們知道,在現實場景中,由于存在端口port復用的情況,服務器可同時支持的TCP連接數跟65,535沒有一一對應關系,事實上,真正影響TCP連接數量的,是服務器的內存以及允許單一進程同時打開文件的數量,因為每創(chuàng)建一個TCP連接都要創(chuàng)建一個socket句柄,每個socket句柄都占用一部分系統內存,當系統內存被占用殆盡,允許的TCP并發(fā)連接數也就到了上限。一般來講,通過增加服務器內存、修改最大文件描述符個數等,可以做到單臺服務器支持10萬+的TCP并發(fā)。
當然,在真實的商用場景下,單臺服務器都會編入分布式集群,通過負載均衡算法動態(tài)的調度不同用戶的請求給最空閑的服務器,如果服務器平均內存使用超過80%的警戒線,那么就會及時采用限流或者擴展集群的方式來保證服務,絕對不會出現服務器的內存被耗盡的情況,那樣就算事故了。
總之,65,535只是Linux系統中可使用端口port數量的上限,端口port數量與TCP連接數量并非完全一一對應的關系,服務器支持的TCP并發(fā)連接數量主要跟服務器的內存以及允許單個進程同時打開的文件數量有關系,通過端口復用及調整服務器參數等手段,單臺服務器支持的TCP并發(fā)連接數是可以高于65,535的。
作為一個資深的Layer4-7層網絡測試人員,回答你的問題:)
其實這個問題,根源在于你不理解服務器是使用IP+端口號方式工作的,看我下面的解釋。
首先,這個說法是正確的,但是有限定。它指的是Linux系統作為client,從它自身發(fā)起的連接不能超過65535個,并且用的是源端口號。
而對于一臺電腦上來說,一個端口號就表示一個進程,所以一臺電腦的最大進程個數為65535。
請看下圖:
這個就是TCP的報文格式,它的頭部一般為20字節(jié),而用來表示源/目端口的字段都是2字節(jié),即16bits,所以2的16次方,最大值為65535(從0開始)。
其實不僅是Linux系統,現在存在的Windows、MAC、Android等系統,都是一樣的。
看下面的兩張圖片,是否理解了呢?
第一張:三臺PC同時訪問服務器,向服務器發(fā)送連接請求:
第二張圖片:服務器回復3臺PC的連接請求:
看到這里,各位小伙伴應該明白為啥服務器能夠處理百萬千萬的并發(fā)了吧?
因為服務器處理數據時,會同時使用 IP和端口號,而不是只單純的使用端口號;
IPv4地址理論上有4,294,967,296,在加上每一臺PC可以有65535個源端口,這樣它們的乘積完全是一個天文數字,完全沒有必要為服務器擔心。
看完上面的內容,小伙伴只需要記住,服務器在實現連接時,并不只使用端口號,還需要使用IP地址,而IP地址理論是有43億左右的,這樣完全不用擔心不夠用的問題。
歡迎關注我,一起學習和討論網絡知識,共同進步,共同成長!
你的理解有誤。65535這個最大值指的是你作為客戶端去連別人,而你作為服務器,別人來連你,理論上是沒有限制的。注意,僅僅理論上。
65535是怎么來的?是TCP協議規(guī)定的端口字段的最大范圍,2個字節(jié),16比特,每一比特有0和2種狀態(tài),按照排列組合,2的16次方,一共就是65536,端口0預留不用,就是65535。
客戶端每發(fā)起一次TCP連接,要消耗一個端口,并獨占該端口,最大只能同時發(fā)起65535個TCP連接,實際上65535這個最大值只是TCP協議的規(guī)定,操作系統還有限制呢,發(fā)起主動連接前1024個端口號(0-1023)都不給用,真實最大只有64512個。
說完客戶端再說服務端。服務端一般都監(jiān)聽某一個端口,比如80的web端口,比如22的ssh端口,比如3306的mysql端口,都是在被動等待別人來連,所以沒有限制。
你如果真要算最大值也能算。TCP連接的唯一性靠四元組,源目的IP,源目的端口,假設服務端只有一個IP,開了一個端口,相當于把兩個固定了,另兩個的范圍一個是0.0.0.0-255.255.255.255,一個是0-65535,一乘就是最大連接數。其實按照比特數最好算,2的32次方乘上個2的16次方,作為服務端最大連接數就是2的48次方。有意義嗎?沒有意義!
前面為什么又說是理論上無限制呢,因為最大的限制不在TCP連接數上,而在硬件上,主要是CPU和內存,一個連接占幾k內存。一個市面上現在普通的物理服務器,最大也就十幾萬并發(fā)連接吧。
題主所述服務器如何應對百萬千萬的并發(fā),現在沒什么好辦法,其實就是堆服務器,一臺十萬,十臺百萬,百臺千萬……我們給這一堆服務器一個高大上的名字,“集群”。
本來不想回答這個問題,因為太簡單,但是上下瀏覽了下,竟然沒一個人答到點子上,不得不說一句。
這個問題說道點子上其實挺簡單。
那就是服務器百萬,千萬并發(fā),并不是同時你認為的“同時”連接。
而是依次排隊通訊。
只是因為服務器性能高,排隊速度很快,所以看似并發(fā)。
那個連接數跟多少萬并發(fā)沒任何關系。
是指不同的服務端口。
而講服務器能支持多少萬并發(fā)的性能,講的是同一個服務,在同一個端口上的并發(fā)。
是通過高速排隊實現的。
至于你說單臺服務器性能不夠,出現了排隊延遲,無法讓人覺得是并發(fā)。那就涉及到服務器陣列的問題了。
這是另一個話題。
本質上是通過多臺服務器聯合工作打破單臺服務器硬件性能瓶頸。
跟這個話題實質上并不是同一個話題。
換句話說,所謂的百萬級并發(fā),千萬級并發(fā),通常意義上來講,都是假并發(fā),實質是排隊通訊。
都是有先來后到的。
只是說,因為性能足夠高,以在多少排隊限度內,讓用戶感覺是在并發(fā)。那就是這個服務器能實現多少級別的“并發(fā)”。
至于你說,要做到真并發(fā)。
這就是同時處理。
這在實踐上是不科學的,因為真并發(fā)之后,為了保障分布部署的服務器的數據一致性,同步數據的數據帶來的處理量會超過真并發(fā)帶來的“好處”。
當然。
實踐中,可以用兩個一千萬級“假并發(fā)”真排隊通訊,通過互相之間的數據同步的“真并發(fā)”,把原本只能實現一千萬級假并發(fā)的兩個服務器,組合成兩千萬級的假并發(fā)。
在硬件性能達到極限的情況下。
這種組合可以讓并發(fā)數實現極限突破。
ucloud云的上億級別的并發(fā)技術就是這樣實現的。
0
回答0
回答0
回答0
回答0
回答0
回答0
回答0
回答0
回答0
回答