天天看點

[譯] 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

資源。資源的種類數量隻會持續增長。

HTTP/2

是針對表現一直不錯的舊協定

HTTP

自從1991年釋出以來這15年的第一次大的更新改動!它為優化現代浏覽器而生。性能更加優越而且不用使用複雜的行為例如

域名分片

(通過多個域名發送資源)或者資源檔案合并`(提供一個整合的大資源而不是多個小資源)

HTTP/2

是目前

web

的新标準,其雛形是 Google 的

SPDY

協定。目前已經被大多數主流浏覽器支援,且很多網站已經通過該協定實作。例如通路 Yahoo 的

Flickr

在使用的是

HTTP/2

協定(截圖時間為2016年7月).

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

HTTP/2 的優勢和注意事項

HTTP/2

HTTP/1.1

的使用沒什麼差別,仍然可以在

body

中使用類

xml

的文法,使用

header

協定頭字段, 狀态碼, cookies, methods, URLs, 等等。開發者熟悉使用的東西都還可以繼續在

HTTP/2

使用。

HTTP/2

的優勢如下:

  1. 多路複用傳輸(Multiplexing):允許浏覽器在單個TCP連接配接中包含多個請求,進而使浏覽器能夠并行地請求所有的資源;
  2. 伺服器推送(Server push):伺服器可以在浏覽器知道需要該資源前,推送給浏覽器(如:CSS、JS、Image),進而通過減少請求數量來加速頁面加載時間;
  3. 流傳輸優先級(Stream priority):允許浏覽器去控制資源的加載優先級,例如,浏覽器先請求

    HTML

    渲染再去加載其他的

    CSS

    JS

    檔案;
  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. 作者希望前端建構工具,如

    Grunt

    Gulp

    Webpack

    将會是以特性被放棄使用,他們使

    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 
...
$ 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 ( letter code) [AU]:US
State or Province Name (full name) [Some-State]:California
...
A challenge password []:
...
$ openssl x509 -req -sha256 -days  -in server.csr -signkey server.key -out server.crt
           

當你通路伺服器的時候,因為浏覽器預設不信任自己簽發的證書,請確定選擇 “進階” 和 “繼續通路 localhost (不安全)” 或者将 localhost 設定成不安全通路的例外。

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

初始化、依賴、入口

通過

npm

,初始化項目

package.json

,安裝依賴

spdy

express

npm init
npm i express spdy --save
           

建立應用的入口檔案

index.js

,主要是引用以及執行個體化

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

const app = express()
           

定義 Express.js 的 route

實作

Express.js

route

app.get('*', (req, res) => {
  res
    .status()
    .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()
    } else {
      console.log('Listening on port: ' + port + '.')
    }
  })
           

最後,

node .

啟動伺服器

檢查結果

通過浏覽器的開發者工具檢視協定,就如剛剛我們檢視

Yahoo 的 Flickr

協定一樣。

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

可以看到,使用 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

我的部落格

繼續閱讀