[譯] Node.js, Express.js 搭建 HTTP/2 服務器

原文:Easy HTTP/2 Server with Node.js and Express.js
做者:Azat Mardan
代碼:http2-express前端


什麼是 HTTP/2

現代互聯網的 TCP/IP 協議發佈於1975年,這項技術在41年前是多麼使人驚訝。自它發佈開始大部分形式,咱們使用 HTTP 和 後續接任者 HTTP/1.1 來實現客戶端和服務端的通信。它能很不錯的傳輸 Web,但今時今日的開發者創建網站的方式已經發生了巨大的改變。存在各式各樣的外部資源連接例如圖片、CSS 文件、JavaScript 資源。資源的種類數量只會持續增加。node

HTTP/2 是針對表現一直不錯的舊協議 HTTP 自從1991年發佈以來這15年的第一次大的升級改動!它爲優化現代瀏覽器而生。性能更加優越並且不用使用複雜的行爲例如域名分片(經過多個域名發送資源)或者資源文件合併`(提供一個整合的大資源而不是多個小資源)git

HTTP/2 是當前 web 的新標準,其雛形是 Google 的 SPDY 協議。當前已經被大多數主流瀏覽器支持,且不少網站已經經過該協議實現。例如訪問 Yahoo 的 Flickr 在使用的是 HTTP/2 協議(截圖時間爲2016年7月).github

Yahoo 的 Flickr 已經在使用 codeHTTP/2/code 協議

HTTP/2 的優點和注意事項

HTTP/2HTTP/1.1 的使用沒什麼區別,仍然能夠在 body 中使用類 xml 的語法,使用 header 協議頭字段, 狀態碼, cookies, methods, URLs, 等等。開發者熟悉使用的東西都還能夠繼續在 HTTP/2 使用。web

HTTP/2的優點以下:express

  1. 多路複用傳輸(Multiplexing):容許瀏覽器在單個TCP鏈接中包含多個請求,從而使瀏覽器可以並行地請求全部的資源;npm

  2. 服務器推送(Server push):服務器能夠在瀏覽器知道須要該資源前,推送給瀏覽器(如:CSS、JS、Image),從而經過減小請求數量來加速頁面加載時間;json

  3. 流傳輸優先級(Stream priority):容許瀏覽器去控制資源的加載優先級,例如,瀏覽器先請求 HTML 渲染再去加載其餘的 CSSJS 文件;瀏覽器

  4. 頭部壓縮(Header compression): HTTP/1.1 請求的頭部老是重複同樣的內容,而 HTTP/2 則強制對全部請求的頭部進行了去重壓縮;緩存

  5. 實際的強制加密(De facto mandatory encryption):雖然加密不是硬性要求的,可是大多數瀏覽器只支持 TLS(HTTPS) 上的 HTTP/2

雖然目前對於 HTTP/2 還不能徹底知足一些苛求,可是直到更好的技術出現之前,當前是一項明顯的技術進步。讓咱們來看看,做爲 Web 開發者須要瞭解的必要知識。大部分適用於 HTTP/1.1 的優化技巧在 HTTP/2 中變成多餘的,其中一些甚至反而會影響 HTTP/2 上的網站性能,例如:

  1. 資源文件合併;

  2. 你也應該中止使用精靈圖(image sprites)、CSS和JS打包,由於只要其中一小部分有改動就會影響客戶端的緩存的做用;在 HTTP/2 協議上更好的方式是使用多個的小文件,而不是一個大文件。

  3. 做者但願前端構建工具,如 GruntGulpWebpack 將會所以特性被放棄使用,他們使 Web 開發更高的複雜度,極高的學習曲線,以及管理項目的依賴關係。

  4. 另外一個適用於 HTTP/1.1 不適用於 HTTP/2 的是,域名分片(爲了繞過TCP並行請求數量限制)。雖然它不必定在全部狀況下有害,但對於 HTTP/2 的多路複用傳輸,這樣作也已經沒好處了。之因此建議不在 HTTP/2 使用域名分片,還由於每一個域名會帶來額外的查詢負載。若是真的有須要,那麼更好的方式是解析多個域名到同一個IP,並且保證你使用的是通配符證書或整合了多域名的證書,從而減小域名查詢的時間。

若想了解更多關於 HTTP/2 的介紹,能夠看看官網

Node.js 搭建 HTTP/2

如今,讓咱們看看怎麼經過 Node.js 搭建 HTTP/2 服務器。

部署證書

建立一個新文件夾以及本身簽發的 SSL 證書。

$ mkdir http2-express 
$ cd http2-express
$ openssl genrsa -des3 -passout pass:x -out server.pass.key 2048
...
$ openssl rsa -passin pass:x -in server.pass.key -out server.key
writing RSA key
$ rm server.pass.key
$ openssl req -new -key server.key -out server.csr
...
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:California
...
A challenge password []:
...
$ openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt

當你訪問服務器的時候,由於瀏覽器默認不信任本身簽發的證書,請確保選擇 「高級」 和 「繼續訪問 localhost (不安全)」 或者將 localhost 設置成不安全訪問的例外。

點擊高級設置

繼續訪問 localhost (不安全)

初始化、依賴、入口

經過 npm ,初始化項目 package.json ,安裝依賴 spdyexpress

npm init
npm i express spdy --save

建立應用的入口文件 index.js ,主要是引用以及實例化

const port = 3000
const spdy = require('spdy')
const express = require('express')
const path = require('path')
const fs = require('fs')

const app = express()

定義 Express.js 的 route

實現 Express.jsroute

app.get('*', (req, res) => {
  res
    .status(200)
    .json({message: 'ok'})
})

設置證書以及啓動 Server

經過 fs.readFileSync() 讀取證書

const options = {
  key: fs.readFileSync(__dirname + '/server.key'),
  cert: fs.readFileSync(__dirname + '/server.crt')
}

而後,設置證書選項到 Express 對象:

spdy
  .createServer(options, app)
  .listen(port, (error) => {
    if (error) {
      console.error(error)
      return process.exit(1)
    } else {
      console.log('Listening on port: ' + port + '.')
    }
  })

最後,node . 啓動服務器

檢查結果

經過瀏覽器的開發者工具查看協議,就如剛剛咱們查看 Yahoo 的 Flickr 協議同樣。

開發者工具檢查協議

能夠看到,使用 Node.js 和 Express.js 配合庫 node-spdy 實現 HTTP/2 簡單易懂。大多數狀況下,對你的業務代碼是基本不須要修改的,想必,你的網站也已經使用了 HTTPS/SSL (除非你的服務器只提供靜態資源,不然你應該使用安全的 HTTPS/SSL ),即便是不使用 HTTP/2 你也能夠替換 HTTP/1.1 而使用 SPDY

固然,在 Node.js 的大環境中,有不少的庫,不僅是 node-spdy 提供 HTTP/2 實現,例如:node-http2

結語

HTTP/2 提供了更多更優的好處,並且不用使用複雜的優化技巧。開始享受 HTTP/2 給你帶來的這些好處。展望光明的將來!

PS:
本文源代碼地址在 http2-express
個人博客

相關文章
相關標籤/搜索