HTTP長連線

littlebirdflying發表於2018-09-22

title: HTTP長連線 date: 2018-09-22 09:59:08 toc: true categories:

  • [web前端,HTTP] tags:
  • HTTP

長連線的概念

HTTP 的請求是在 TCP 連線的基礎上傳送的,而 TCP連結分為長連線短連線

長連線:HTTP 傳送請求時,要先建立一個 TCP 連線,並在 TCP 連線上把 HTTP 請求的內容傳送並且接收完返回,這是一次請求完成,瀏覽器與伺服器進行協商是否關閉 TCP 連結,若不關閉 TCP 連線會有一定的消耗,好處是如果還有請求可以直接在這個 TCP 連線上傳送,不需要經過建立時三次握手的消耗。

短連線:若關閉 TCP 連線,下次請求需要重新建立,這時會有網路延遲的開銷,好處是每次請求完關閉 TCP 連線,減少客戶端和服務端連線的併發數。

實際情況中,網站的併發量比較大,如果每次都重新建立連線,導致建立過程發生太多,導致建立 TCP 連線的開銷,比保持長連線還要高一些。而且長連線可以設定關閉時間,在一定時間內沒有請求自動關閉。一般情況都會保持長連線

百度示例

示例,開啟百度首頁,開啟控制檯-network,name那一行,右鍵選中 connection ID,代表 tcp 連線 的 id,根據他區分是否是同一個 tcp 連線。

長連線的使用

命令列 node server.js 啟動服務,locahost:8888訪問,檢視 network的 connection ID 和 waterfall。

設定網速 fast 3G

// server.js
const http = require('http')
const fs = require('fs')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  const html = fs.readFileSync('test.html', 'utf8')
  const img = fs.readFileSync('test.jpg')
  if (request.url === '/') {
    response.writeHead(200, {
      'Content-Type': 'text/html',
    })
    response.end(html)
  } else {
    response.writeHead(200, {
      'Content-Type': 'image/jpg'
    })
    response.end(img)
  }

}).listen(8888)

console.log('server listening on 8888')
複製程式碼
// test.html
  <img src="/test1.jpg" alt="">
  <img src="/test2.jpg" alt="">
  <img src="/test3.jpg" alt="">
  <img src="/test4.jpg" alt="">
  <img src="/test5.jpg" alt="">
  <img src="/test6.jpg" alt="">
  <img src="/test7.jpg" alt="">
  <img src="/test11.jpg" alt="">
  <img src="/test12.jpg" alt="">
  <img src="/test13.jpg" alt="">
  <img src="/test14.jpg" alt="">
  <img src="/test15.jpg" alt="">
  <img src="/test16.jpg" alt="">
  <img src="/test17.jpg" alt="">
  <img src="/test111.jpg" alt="">
  <img src="/test112.jpg" alt="">
  <img src="/test113.jpg" alt="">
  <img src="/test114.jpg" alt="">
  <img src="/test115.jpg" alt="">
  <img src="/test116.jpg" alt="">
  <img src="/test117.jpg" alt="">
複製程式碼

Chrome瀏覽器的 TCP 連線的併發限制,6個 TCP 連線後,第7個 TCP連線有新的 TCP 連線空出來

HTTP長連線

預設是長連線

HTTP長連線

關閉長連線

通過設定 'Connection': 'close' 來關閉預設的長連線。

const http = require('http')
const fs = require('fs')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  const html = fs.readFileSync('test.html', 'utf8')
  const img = fs.readFileSync('test.jpg')
  if (request.url === '/') {
    response.writeHead(200, {
      'Content-Type': 'text/html',
      'Connection': 'close' // 預設是 keep-alive
    })
    response.end(html)
  } else {
    response.writeHead(200, {
      'Content-Type': 'image/jpg',
      'Connection': 'close' // 預設是 keep-alive
    })
    response.end(img)
  }

}).listen(8888)

console.log('server listening on 8888')
複製程式碼

沒有重複利用 TCP 連線,並且每個 connection id 都不同

HTTP長連線

正常情況下都是合理利用 Connection:'keep-alive',並設定一個自動關閉時間,在服務端進行控制

HTTP 2 通道複用

HTTP2 通道複用,在 TCP 連線上可以併發的傳送 HTTP 請求,意味著連結網站是隻需要一個 TCP 連線。google.com的頁面都是用的 HTTP2。

它的 connection id 都是一個,注意,同域 id 才相同,不同域需要建立 tcp 連線,這樣降低了開銷,速度有質的提升。

HTTP長連線

總結

http 請求是在 tcp 連線上傳送的,一個 tcp 連線可以傳送多個 http 請求

在 http 1.1 中 http 請求在 tcp 上進行傳送有先後順序,為了提高效能,需要使用併發 tcp 連線的方式。

在 http 2 中,可以在一個 tcp 連線上併發的傳送 http 請求,所以只需要開一個 tcp 連線。

長連線的概念

相關文章