中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

影響http性能的常見因素有哪些

發布時間:2020-12-02 10:10:00 來源:億速云 閱讀:157 作者:小新 欄目:web開發

小編給大家分享一下影響http性能的常見因素有哪些,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討吧!

我們這里討論HTTP性能是建立在一個最簡單模型之上就是單臺服務器的HTTP性能,當然對于大規模負載均衡集群也適用畢竟這種集群也是由多個HTTTP服務器的個體所組成。另外我們也排除客戶端或者服務器本身負載過高或者HTTP協議實現的軟件使用不同的IO模型,另外我們也忽略DNS解析過程和web應用程序開發本身的缺陷。

從TCP/IP模型來看,HTTP下層就是TCP層,所以HTTP的性能很大程度上取決于TCP性能,當然如果是HTTPS的就還要加上TLS/SSL層,不過可以肯定的是HTTPS性能肯定比HTTP要差,其通訊過程這里都不多說總之層數越多性能損耗就越嚴重。

在上述條件下,最常見的影響HTTP性能的包括:

  • TCP連接建立,也就是三次握手階段

  • TCP慢啟動

  • TCP延遲確認

  • Nagle算法

  • TIME_WAIT積累與端口耗盡

  • 服務端端口耗盡

  • 服務端HTTP進程打開文件數量達到最大

TCP連接建立

通常如果網絡穩定TCP連接建立不會消耗很多時間而且也都會在合理耗時范圍內完成三次握手過程,但是由于HTTP是無狀態的屬于短連接,一次HTTP會話接受后會斷開TCP連接,一個網頁通常有很多資源這就意味著會進行很多次HTTP會話,而相對于HTTP會話來說TCP三次握手建立連接就會顯得太耗時了,當然可以通過重用現有連接來減少TCP連接建立次數。

TCP慢啟動

TCP擁塞控制手段1,在TCP剛建立好之后的最初傳輸階段會限制連接的最大傳輸速度,如果數據傳輸成功,后續會逐步提高傳輸速度,這就TCP慢啟動。慢啟動限制了某一時刻可以傳輸的IP分組2數量。那么為什么會有慢啟動呢?主要是為了避免網絡因為大規模的數據傳輸而癱瘓,在互聯網上數據傳輸很重要的一個環節就是路由器,而路由器本身的速度并不快加之互聯網上的很多流量都可能發送過來要求其進行路由轉發,如果在某一時間內到達路由器的數據量遠大于其發送的數量那么路由器在本地緩存耗盡的情況下就會丟棄數據包,這種丟棄行為被稱作擁塞,一個路由器出現這種狀況就會影響很多條鏈路,嚴重的會導致大面積癱瘓。所以TCP通信的任何一方需要進行擁塞控制,而慢啟動就是擁塞控制的其中一種算法或者叫做機制。
你設想一種情況,我們知道TCP有重傳機制,假設網絡中的一個路由器因為擁塞而出現大面積丟包情況,作為數據的發送方其TCP協議棧肯定會檢測到這種情況,那么它就會啟動TCP重傳機制,而且該路由器影響的發送方肯定不止你一個,那么大量的發送方TCP協議棧都開始了重傳那這就等于在原本擁塞的網絡上發送更多的數據包,這就等于火上澆油。

通過上面的描述得出即便是在正常的網絡環境中,作為HTTP報文的發送方與每個請求建立TCP連接都會受到慢啟動影響,那么又根據HTTP是短連接一次會話結束就會斷開,可以想象客戶端發起HTTP請求剛獲取完web頁面上的一個資源,HTTP就斷開,有可能還沒有經歷完TCP慢啟動過程這個TCP連接就斷開了,那web頁面其他的后續資源還要繼續建立TCP連接,而每個TCP連接都會有慢啟動階段,這個性能可想而知,所以為了提升性能,我們可以開啟HTTP的持久連接也就是后面要說的keepalive。

另外我們知道TCP中有窗口的概念,這個窗口在發送方和接收方都有,窗口的作用一方面保證了發送和接收方在管理分組時變得有序;另外在有序的基礎上可以發送多個分組從而提高了吞吐量;還有一點就是這個窗口大小可以調整,其目的是避免發送方發送數據的速度比接收方接收的速度快。窗口雖然解決了通信雙發的速率問題,可是網絡中會經過其他網絡設備,發送方怎么知道路由器的接收能力呢?所以就有了上面介紹的擁塞控制。

TCP延遲確認

首先要知道什么是確認,它的意思就是發送方給接收方發送一個TCP分段,接收方收到以后要回傳一個確認表示收到,如果在一定時間內發送方沒有收到該確認那么就需要重發該TCP分段。

確認報文通常都比較小,也就是一個IP分組可以承載多個確認報文,所以為了避免過多的發送小報文,那么接收方在回傳確認報文的時候會等待看看有沒有發給接收方的其他數據,如果有那么就把確認報文和數據一起放在一個TCP分段中發送過去,如果在一定時間內容通常是100-200毫秒沒有需要發送的其他數據那么就將該確認報文放在單獨的分組中發送。其實這么做的目的也是為了盡可能降低網絡負擔。

一個通俗的例子就是物流,卡車的載重是一定的,假如是10噸載重,從A城市到B城市,你肯定希望它能盡可能的裝滿一車貨而不是來了一個小包裹你就立刻起身開向B城市。

所以TCP被設計成不是來一個數據包就馬上返回ACK確認,它通常都會在緩存中積攢一段時間,如果還有相同方向的數據就捎帶把前面的ACK確認回傳過去,但是也不能等的時間過長否則對方會認為丟包了從而引發對方的重傳。

對于是否使用以及如何使用延遲確認不同操作系統會有不同,比如Linux可以啟用也可以關閉,關閉就意味著來一個就確認一個,這也是快速確認模式。

需要注意的是是否啟用或者說設置多少毫秒,也要看場景。比如在線游戲場景下肯定是盡快確認,SSH會話可以使用延遲確認。

對于HTTP來說我們可以關閉或者調整TCP延遲確認。

Nagle算法

這個算法其實也是為了提高IP分組利用率以及降低網絡負擔而設計,這里面依然涉及到小報文和全尺寸報文(按以太網的標準MTU1500字節一個的報文計算,小于1500的都算非全尺寸報文),但是無論小報文怎么小也不會小于40個字節,因為IP首部和TCP首部就各占用20個字節。如果你發送一個50個字節小報文,其實這就意味著有效數據太少,就像延遲確認一樣小尺寸包在局域網問題不大,主要是影響廣域網。

這個算法其實就是如果發送方當前TCP連接中有發出去但還沒有收到確認的報文的時候,那么此時如果發送方還有小報文要發送的話就不能發送而是要放到緩沖區等待之前發出報文的確認,收到確認之后,發送方會收集緩存中同方向的小報文組裝成一個報文進行發送。其實這也就意味著接收方返回ACK確認的速度越快,發送方發送數據也就越快。

現在我們說說延遲確認和Nagle算法結合將會帶來的問題。其實很容易看出,因為有延遲確認,那么接收方則會在一段時間內積攢ACK確認,而發送方在這段時間內收不到ACK那么也就不會繼續發送剩下的非全尺寸數據包(數據被分成多個IP分組,發送方要發送的響應數據的分組數量不可能一定是1500的整數倍,大概率會發生數據尾部的一些數據就是小尺寸IP分組),所以你就看出這里的矛盾所在,那么這種問題在TCP傳輸中會影響傳輸性能那么HTTP又依賴TCP所以自然也會影響HTTP性能,通常我們會在服務器端禁用該算法,我們可以在操作系統上禁用或者在HTTP程序中設置TCP_NODELAY來禁用該算法。比如在Nginx中你可以使用tcp_nodelay on;來禁用。

TIME_WAIT積累與端口耗盡3

這里指的是作為客戶端的一方或者說是在TCP連接中主動關閉的一方,雖然服務器也可以主動發起關閉,但是我們這里討論的是HTTP性能,由于HTTP這種連接的特性,通常都是客戶端發起主動關閉,

客戶端發起一個HTTP請求(這里說的是對一個特定資源的請求而不是打開一個所謂的主頁,一個主頁有N多資源所以會導致有N個HTTP請求的發起)這個請求結束后就會斷開TCP連接,那么該連接在客戶端上的TCP狀態會出現一種叫做TIME_WAIT的狀態,從這個狀態到最終關閉通常會經過2MSL4的時長,我們知道客戶端訪問服務端的HTTP服務會使用自己本機隨機高位端口來連接服務器的80或者443端口來建立HTTP通信(其本質就是TCP通信)這就意味著會消耗客戶端上的可用端口數量,雖然客戶端斷開連接會釋放這個隨機端口,不過客戶端主動斷開連接后,TCP狀態從TIME_WAIT到真正CLOSED之間的這2MSL時長內,該隨機端口不會被使用(如果客戶端又發起對相同服務器的HTTP訪問),其目的之一是為了防止相同TCP套接字上的臟數據。通過上面的結論我們就知道如果客戶端對服務器的HTTP訪問過于密集那么就有可能出現端口使用速度高于端口釋放速度最終導致因沒有可用隨機端口而無法建立連接。

上面我們說過通常都是客戶端主動關閉連接,

TCP/IP詳解 卷1 第二版,P442,最后的一段寫到 對于交互式應用程序而言,客戶端通常執行主動關閉操作并進入TIME_WAIT狀態,服務器通常執行被動關閉操作并且不會直接進入TIME_WAIT狀態。

不過如果web服務器并且開啟了keep-alive的話,當達到超時時長服務器也會主動關閉。(我這里并不是說TCP/IP詳解錯了,而是它在那一節主要是針對TCP來說,并沒有引入HTTP,而且它說的是通常而不是一定)

我使用Nginx做測試,并且在配置文件中設置了keepalive_timeout 65s;,Nginx的默認設置是75s,設置為0表示禁用keepalive,如下圖:

影響http性能的常見因素有哪些

下面我使用Chrom瀏覽器訪問這個Nginx默認提供的主頁,并通過抓包程序來監控整個通信過程,如下圖:

影響http性能的常見因素有哪些

從上圖可以看出來在有效數據傳送完畢后,中間出現了Keep-Alive標記的通信,并且在65秒內沒有請求后服務器主動斷開連接,這種情況你在Nginx的服務器上就會看到TIME_WAIT的狀態。

服務端端口耗盡

有人說Nginx監聽80或者443,客戶端都是連接這個端口,服務端怎么會端口耗盡呢?就像下圖一樣(忽略圖中的TIME_WAIT,產生這個的原因上面已經說過了是因為Nginx的keepalive_timeout設置導致的)

影響http性能的常見因素有哪些

其實,這取決于Nginx工作模式,我們使用Nginx通常都是讓其工作在代理模式,這就意味著真正的資源或者數據在后端Web應用程序上,比如Tomcat。代理模式的特點是代理服務器代替用戶去后端獲取數據,那么此時相對于后端服務器來說,Nginx就是一個客戶端,這時候Nginx就會使用隨機端口來向后端發起請求,而系統可用隨機端口范圍是一定的,可以使用sysctl net.ipv4.ip_local_port_range命令來查看服務器上的隨機端口范圍。

通過我們之前介紹的延遲確認、Nagle算法以及代理模式下Nginx充當后端的客戶端角色并使用隨機端口連接后端,這就意味著服務端的端口耗盡風險是存在的。隨機端口釋放速度如果比與后端建立連接的速度慢就有可能出現。不過一般不會出現這個情況,至少我們公司的Nginx我沒有發現有這種現象產生。因為首先是靜態資源都在CDN上;其次后端大部分都是REST接口提供用戶認證或者數據庫操作,這些操作其實后端如果沒有瓶頸的話基本都很快。不過話說回來如果后端真的有瓶頸且擴容或者改架構成本比較高的話,那么當面對大量并發的時候你應該做的是限流防止后端被打死。

服務端HTTP進程打開文件數量達到最大

我們說過HTTP通信依賴TCP連接,一個TCP連接就是一個套接字,對于類Unix系統來說,打開一個套接字就是打開一個文件,如果有100個請求連接服務端,那么一旦連接建立成功服務端就會打開100個文件,而Linux系統中一個進程可以打開的文件數量是有限的ulimit -f,所以如果這個數值設置的太小那么也會影響HTTP連接。而對以代理模式運行的Nginx或者其他HTTP程序來說,通常一個連接它就要打開2個套接字也就會占用2個文件(命中Nginx本地緩存或者Nginx直接返回數據的除外)。所以對于代理服務器這個進程可打開的文件數量也要設置的大一點。

持久連接Keepalive

首先我們要知道keepalive可以設置在2個層面上,且2個層面意義不同。TCP的keepalive是一種探活機制,比如我們常說的心跳信息,表示對方還在線,而這種心跳信息的發送由有時間間隔的,這就意味著彼此的TCP連接要始終保持打開狀態;而HTTP中的keep-alive是一種復用TCP連接的機制,避免頻繁建立TCP連接。所以一定明白TCP的Keepalive和HTTP的Keep-alive不是一回事

HTTP的keep-alive機制

非持久連接會在每個HTTP事務完成后斷開TCP連接,下一個HTTP事務則會再重新建立TCP連接,這顯然不是一種高效機制,所以在HTTP/1.1以及HTTP/1.0的增強版本中允許HTTP在事務結束后將TCP連接保持打開狀態,以便后續的HTTP事務可以復用這個連接,直到客戶端或者服務器主動關閉該連接。持久連接減少了TCP連接建立的次數同時也最大化的規避了TCP慢啟動帶來的流量限制。

相關教程:HTTP視頻教程

影響http性能的常見因素有哪些

再來看一下這張圖,圖中的keepalive_timeout 65s設置了開啟http的keep-alive特性并且設置了超時時長為65秒,其實還有比較重要的選項是keepalive_requests 100;它表示同一個TCP連接最多可以發起多少個HTTP請求,默認是100個。

在HTTP/1.0中keep-alive并不是默認使用的,客戶端發送HTTP請求時必須帶有Connection: Keep-alive的首部來試圖激活keep-alive,如果服務器不支持那么將無法使用,所有請求將以常規形式進行,如果服務器支持那么在響應頭中也會包括Connection: Keep-alive的信息。

在HTTP/1.1中默認就使用Keep-alive,除非特別說明,否則所有連接都是持久的。如果要在一個事務結束后關閉連接,那么HTTP的響應頭中必須包含Connection: CLose首部,否則該連接會始終保持打開狀態,當然也不能總是打開,也必須關閉空閑連接,就像上面Nginx的設置一樣最多保持65秒的空閑連接,超過后服務端將會主動斷開該連接。

TCP的keepalive

在Linux上沒有一個統一的開關去開啟或者關閉TCP的Keepalive功能,查看系統keepalive的設置sysctl -a | grep tcp_keepalive,如果你沒有修改過,那么在Centos系統上它會顯示:

net.ipv4.tcp_keepalive_intvl = 75   # 兩次探測直接間隔多少秒
net.ipv4.tcp_keepalive_probes = 9   # 探測頻率
net.ipv4.tcp_keepalive_time = 7200  # 表示多長時間進行一次探測,單位秒,這里也就是2小時

按照默認設置,那么上面的整體含義就是2小時探測一次,如果第一次探測失敗,那么過75秒再探測一次,如果9次都失敗就主動斷開連接。

如何開啟Nginx上的TCP層面的Keepalive,在Nginx中有一個語句叫做listen它是server段里面用于設置Nginx監聽在哪個端口的語句,其實它后面還有其他參數就是用來設置套接字屬性的,看下面幾種設置:

# 表示開啟,TCP的keepalive參數使用系統默認的
listen       80 default_server so_keepalive=on;
# 表示顯式關閉TCP的keepalive
listen       80 default_server so_keepalive=off;
# 表示開啟,設置30分鐘探測一次,探測間隔使用系統默認設置,總共探測10次,這里的設
# 置將會覆蓋上面系統默認設置
listen       80 default_server so_keepalive=30m::10;

所以是否要在Nginx上設置這個so_keepalive,取決于特定場景,千萬不要把TCP的keepalive和HTTP的keepalive搞混淆,因為Nginx不開啟so_keepalive也不影響你的HTTP請求使用keep-alive特性。如果客戶端和Nginx直接或者Nginx和后端服務器之間有負載均衡設備的話而且是響應和請求都會經過這個負載均衡設備,那么你就要注意這個so_keepalive了。比如在LVS的直接路由模式下就不受影響,因為響應不經過
LVS,不過要是NAT模式就需要留意,因為LVS保持TCP會話也有一個時長,如果該時長小于后端返回數據的時長那么LVS就會在客戶端還沒有收到數據的情況下斷開這條TCP連接。


  1. TCP擁塞控制有一些算法,其中就包括TCP慢啟動、擁塞避免等算法?

  2. 有些地方也叫做IP分片但都是一個意思,至于為什么分片簡單來說就是受限于數據鏈路層,不同的數據鏈路其MTU不同,以太網的是1500字節,在某些場景會是1492字節;FDDI的MTU又是另外一種大小,單純考慮IP層那么IP數據包最大是65535字節?

  3. 在《HTTP權威指南》P90頁中并沒有說的特別清楚,這種情況是相對于客戶端來說還是服務端,因為很有可能讓人誤解,當然并不是說服務端不會出現端口耗盡的情況,所以我這里才增加了2項內容?

  4. 最長不會超過2分鐘?

看完了這篇文章,相信你對影響http性能的常見因素有哪些有了一定的了解,想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

丰城市| 南宫市| 亚东县| 嫩江县| 商都县| 渭南市| 洪江市| 秀山| 安陆市| 盐山县| 郓城县| 天等县| 台南市| 阳曲县| 东海县| 厦门市| 延津县| 修水县| 青州市| 集贤县| 中阳县| 石台县| 盘山县| 柯坪县| 富蕴县| 富民县| 开封市| 乌拉特中旗| 弥勒县| 桃源县| 印江| 宁陵县| 达拉特旗| 清徐县| 万山特区| 高邮市| 定州市| 色达县| 沿河| 永济市| 秭归县|