+86 135 410 16684Mon. - Fri. 10:00-22:00

用 AWS CloudFront 加速 Rails 網站

用 AWS CloudFront 加速 Rails 網站

用 AWS CloudFront 加速 Rails 網站

CloudFront 是 AWS 提供的 CDN 服務,可以讓你的網站透過 AWS 全球的節 點網路加速傳輸到使用者的裝置上。

為什麼要用 CloudFront 或任何 CDN?

以 AWS 舉例來說,傳統在台灣的團隊使用 AWS 時會選用 ap-northeast-1 region,也就是東京區的機房,使用者從台灣連線需要橫跨東海連到日本東京才能存取到愛料理的服務。

然而 AWS 除了全球有 13 個 regions 之外,在全球也有 58 個 edges,這些 edge 不提供傳統的 EC2 / RDS 等服務,在 AWS 設定中也沒辦法指定,但這些 edge 會加速 CloudFront 的資料傳輸以及 Route 53 的 DNS 域名解析,而其中在台北便有一個 edge。

因此當我們替原本在東京 region 的網站加上 CloudFront 之後,在台灣的使用者只需要連線到 AWS 在台北的 edge 便可以存取到愛料理的內容,速度上當然快上了不少。

靜態內容與動態內容

談到 CloudFront 或 CDN 常常會有個迷思是只能用來加速靜態內容,比方說像是圖片、前端的 JavaScript 或是 CSS 檔案等,許多線上的教學文件也都是以這個方向為主。

背後的原因不外乎是認為網站的頁面都是動態產生,沒辦法被快取的刻板映像。然而實際上:

  1. 很多頁面其實是可以被快取的,像是文章頁面內容很少會更新
  2. 根據使用者客製化的頁面,也可以考慮將動態內容放到前端產生
  3. CDN 除了快取之外,網路連線效能的優化對使用者也很有幫助

近期 AWS 也宣布了 CloudFront 對 HTTP/2 的支援,速度更快、使用體驗也更好。

SSL 設定:AWS Certificate Manager 與 SNI

使用 CloudFront 的另外一個優點是可以使用 AWS 提供免費的 SSL 憑證。你可以使用 AWS Certificate Manager 建立憑證,需要注意的是無論你的來源機器是開在哪個 AWS region,你都需要在 us-east-1 區的 Certificate Manager 建立憑證,才可以在 CloudFront 設定中找到。

而在設定 SSL 時會遇到是否要使用 SNI 的選項:

伺服器名稱指示 (SNI) 可允許多個網域透過同一個 IP 地址為 SSL 流量提供服務。

多數的現代瀏覽器都支援 SNI,在我們部署上線的經驗中,會需要考慮的不相容裝置或瀏覽器只有:

  • Android 2.x
  • Internet Explorer 在 Windows XP 上的任何版本
  • Java 6 以下的版本

前兩者在愛料理使用者的佔比相當的低,實際上啟用 SNI 之後也未曾收到使用者抱怨。然而 Java 6 若是有跟一些第三方金流廠商或是政府單位串接 Webhooks 時則有可能遇到、需要留意。

不使用 SNI 的話則是要向 AWS 購買獨立的 IP 地址,價格為 $600 美金一個月。

X-Forwarded-For 設定

當部署 AWS CloudFront ,你可能會發現後面的 Rails 伺服器沒辦法正確取得使用者的 IP,而會變成取得到 AWS CloudFront 伺服器的 IP。

這原因是 Ruby on Rails 在 ActionDispatch 中有一層 RemoteIp Rack middleware 會檢查 X-Forwarded-For 這個 HTTP header 的參數值,只有在白名單中的 IPs 才會被接受作為合法的 proxy。

我們可以透過查詢 AWS 公開的伺服器 IP 地址列表,並且新增如下方範例檔案到 config/initializers 來解決問題。

trusted_proxies = [52.84.0.0/15,
54.182.0.0/16,
54.192.0.0/16,
54.230.0.0/16,
54.239.128.0/18,
54.239.192.0/19,
54.240.128.0/18,
204.246.164.0/22,
204.246.168.0/22,
204.246.174.0/23,
204.246.176.0/20,
上述檔案放到 config/initializers/cloudfront.rb

參考資料