了解並測量HTTP時間有助於我們發現客戶端到伺服器或伺服器到伺服器之間的通訊效能瓶頸。 本文介紹了HTTP請求中的時間開銷,並展示如何在Node.js中進行測量。
在我們開始了解HTTP時間開銷之前,讓我們先來看看一些基本的概念:
IP(互聯網協議):IP是網絡層協議,涉及網絡尋址和路由。 IP負責根據一個或多個IP網路上的封包頭將封包從來源主機傳送到目標主機。 它也定義了封裝要傳遞的資料的資料包結構。
DNS(網域名稱伺服器):DNS是一種分層分散式命名系統,用於將諸如risingstack.com的人類可讀主機名稱解析為機器可讀的IP位址。
TCP(傳輸控制協定):TCP標準定義如何在應用程式之間建立和維護網路對話以交換資料。 TCP在透過IP網路通訊的主機上執行的應用程式之間提供可靠,有序和錯誤檢查的八位元組流。 HTTP客戶端透過建立TCP連線來發起請求。
SSL / TLS(傳輸層安全性):TLS是一種透過電腦網路提供通訊安全性的加密協定。 SSL(安全通訊端層)是TLS的不建議使用的前身。 TLS和SSL都使用憑證建立安全連線。 SSL憑證不依賴加密協定(如TLS),憑證包含金鑰對:公鑰和私鑰。 這些密鑰一起工作,建立一個加密的連接。
現在我們來看看通常HTTP請求的時間表:
DNS查找:執行DNS查找所花費的時間。 DNS查找將網域名稱解析為IP位址。 每個新的網域需要一個完整的往返行程來進行DNS查找。 當目的地已經是IP位址時,沒有DNS查找。
TCP連線:在來源主機和目標主機之間建立TCP連線所需的時間。 必須在多步驟握手過程中正確建立連線。 TCP連線由作業系統管理,如果基礎TCP連線無法建立,則OS範圍的TCP連線逾時將會進入我們應用程式中的逾時設定。
TLS握手:完成TLS握手的時間。 在握手過程中,端點交換認證和金鑰以建立或復原安全會話。 沒有HTTPS請求的不需要TLS握手。
第一個位元組的時間(TTFB):等待初始回應的時間。 此時間除了等待伺服器處理請求和傳遞回應所花費的時間之外,還可以擷取往返伺服器的延遲。
內容傳輸:接收回應資料所花費的時間。 回應資料的大小和可用的網路頻寬決定其持續時間。
如何透過HTTP時間開銷來幫助發現效能瓶頸?
例如,如果您的DNS查詢所花費的時間比預期的要長,那麼問題可能是您的DNS提供者或DNS快取設定。
緩慢的內容傳輸可能是由效率低下的反應機構引起的,例如發回太多的資料(未使用的JSON屬性等)或緩慢的連接。
測量Node.js中的HTTP時間開銷
為了測量Node.js中的HTTP時間開銷,我們需要訂閱特定的請求,回應和套接字事件。 這是一個簡短的程式碼片段,展示瞭如何在Node.js中執行此操作,此範例僅關注時序:
const timings = { // use process.hrtime() as it's not a subject of clock drift startAt: process.hrtime(), dnsLookupAt: undefined, tcpConnectionAt: undefined, tlsHandshakeAt: undefined, firstByteAt: undefined, endAt: undefined } const req = http.request({ ... }, (res) => { res.once('readable', () => { timings.firstByteAt = process.hrtime() }) res.on('data', (chunk) => { responseBody += chunk }) res.on('end', () => { timings.endAt = process.hrtime() }) }) req.on('socket', (socket) => { socket.on('lookup', () => { timings.dnsLookupAt = process.hrtime() }) socket.on('connect', () => { timings.tcpConnectionAt = process.hrtime() }) socket.on('secureConnect', () => { timings.tlsHandshakeAt = process.hrtime() }) })
DNS查找只會發生在有網域的時候:
/ There is no DNS lookup with IP address const dnsLookup = dnsLookupAt !== undefined ? getDuration(startAt, dnsLookupAt) : undefined
TCP連線在主機解析後立即發生:
const tcpConnection = getDuration((dnsLookupAt || startAt), tcpConnectionAt)
TLS握手(SSL)只能使用https協定:
// There is no TLS handshake without https const tlsHandshake = tlsHandshakeAt !== undefined ? getDuration(tcpConnectionAt, tlsHandshakeAt) : undefined
我們等待伺服器開始發送第一個位元組:
const firstByte = getDuration((tlsHandshakeAt || tcpConnectionAt), firstByteAt)
總持續時間從開始和結束日期計算:
const total = getDuration(startAt, endAt)
看到整個例子,看看我們的https://github.com/RisingStac...倉庫。
測量時間的工具
現在我們知道如何使用Node測量HTTP時間,我們來討論可用來了解HTTP請求的現有工具。
request module
著名的request module具有測量HTTP定時的內建方法。 您可以使用time屬性啟用它。
const request = require('request') request({ uri: 'https://risingstack.com', method: 'GET', time: true }, (err, resp) => { console.log(err || resp.timings) })
分散式追蹤
可以使用分散式追蹤工具收集HTTP定時,並在時間軸上可視化它們。 這樣,您可以全面了解後台發生的情況,以及建構分散式系統的實際成本是多少。
RisingStack的opentracing-auto庫具有內建的標誌,可透過OpenTracing收集所有HTTP時間。
在Jaeger中使用opentracing-auto的HTTP請求時序。
總結
使用Node.js測量HTTP時間可以幫助您發現效能瓶頸。 Node生態系統提供了很好的工具來從應用程式中提取這些指標。
相關推薦:
以上是Node.js測量HTTP所花費的時間的詳細內容。更多資訊請關注PHP中文網其他相關文章!