這裡記錄在 CentOS Linux 7 中自行編譯 Nginx + PageSpeed + Brotli 的過程。

最近我嘗試各種方式,想讓 Nginx 網頁伺服器的效能再提高一些,在校調了 Nginx 與 PHP-FPM 的基本設定,以及啟用了 FastCGI Cache 快取之後,接著考慮 Google 的 PageSpeed 模組Brotli 壓縮模組,而這兩個工具都不是 Nginx 內建的,所以若想使用的話,就必須自己重新編譯 Nginx。

本篇文章所記錄的流程,是我自己在工作時所記錄下來的,並不是用來教學的內容,許多細部的參數在不同系統、不同軟體版本之下,都會有一些差異,所以請大家在實做時不要用複製貼上的方式來操作,否則可能會把整台伺服器搞壞。

安裝編譯用套件

使用 yum 安裝一些編譯用的工具與函式庫,我從網路上找了好久,安裝的套件列表大家寫的都不太一樣,這一串是我找到最長的,若不需要的可自己拿掉:

# 安裝套件
sudo yum install git cmake gc gcc gcc-c++ pcre-devel zlib-devel \
  make wget openssl-devel libxml2-devel libxslt-devel gd-devel \
  perl-ExtUtils-Embed GeoIP-devel gperftools gperftools-devel \
  libatomic_ops-devel perl-ExtUtils-Embed

下載 ngx_brotli 原始碼

ngx_brotli 是 Brotli 的 Nginx 模組,請從 ngx_brotli 的 GitHub 網站下載其原始碼:

# 下載 Brotli
cd
git clone https://github.com/google/ngx_brotli.git
cd ngx_brotli
git submodule update --init --recursive

整理 Nginx 編譯參數

由於我想要直接把系統 Nginx 直接抽換成自己編譯的版本(這樣就可以不需要自己寫太多的設定),所以先看一下系統 Nginx 編譯參數:

nginx -V

輸出的欄位中會有一項 configure arguments,這個就是該 Nginx 當初編譯使用的參數,請自己詳細查看每個參數,保留需要用的模組以及必要的路徑相關設定,自己整理出一串適合自己的參數,然後再額外加上 --add-module=${HOME}/ngx_brotli,將 Brotli 納入。以下是一個範例:

--add-module=${HOME}/ngx_brotli --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-ipv6 --with-http_auth_request_module --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-google_perftools_module

若以 --add-module 加入 Nginx 模組時,它會直接跟主程式放在一起,如果想要編譯成可以動態載入的模組,可以改用 --add-dynamic-module 來加入模組,爾後若需要時再使用 load_module 載入。

編譯 Nginx

參考 PageSpeed 編譯說明文件,使用官方提供的自動編譯指令稿,並把上面整理好的編譯參數放進 --additional-nginx-configure-arguments 中,執行後即可自動編譯安裝:

bash <(curl -f -L -sS https://ngxpagespeed.com/install) \
  --nginx-version latest \
  --additional-nginx-configure-arguments '--add-module=${HOME}/ngx_brotli --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-ipv6 --with-http_auth_request_module --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-google_perftools_module'

執行這個自動編譯與安裝的指令稿之後,會自動逐步完成所有編譯與安裝的動作,理論上來說我們使用跟系統 Nginx 相同的編譯參數,只要版本不要差異太大,安裝之後會把系統的 Nginx 覆蓋掉,直接就可以使用,不過這種方式的風險非常高,也有可能裝下去之後,整理網頁伺服器就無法運作了,所以如果要這樣裝,一定要事先在測試的機器上充分測試。

這個自動編譯與安裝的指令稿其實就只是幫我們下載必要的東西,並且執行 make 相關的指令而已,後來如果想要調整細部參數、重新安裝的話,只要在既有的 Nginx 原始碼目錄執行 configuremake 等指令即可,跟自己完全手動的做法類似。

若幸運的話,只要重新啟動 Nginx 伺服器,就可以直接使用新的 Nginx 伺服器了:

sudo systemctl restart nginx

Brotli 設定

開啟 Nginx 的設定檔 /etc/nginx/nginx.conf,在 http 區塊加入以下設定:

http {
  # [略]

  # 啟用 Brotli
  brotli on;
  brotli_static on;
  brotli_comp_level 6;
  brotli_types
    text/plain
    text/javascript
    text/css
    text/xml
    text/x-component
    application/javascript
    application/x-javascript
    application/xml
    application/json
    application/xhtml+xml
    application/rss+xml
    application/atom+xml
    application/x-font-ttf
    application/vnd.ms-fontobject
    image/svg+xml
    image/x-icon
    font/opentype;

  # [略]
}

PageSpeed 設定

PageSpeed 的設定相當複雜,以下是最簡單的設定方式:

server {
  # [略]

  # 啟用 PageSpeed
  pagespeed on;

  # 設定 PageSpeed 快取目錄
  pagespeed FileCachePath /var/ngx_pagespeed_cache;

  # Ensure requests for pagespeed optimized resources go to the pagespeed handler
  # and no extraneous headers get set.
  location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" {
    add_header "" "";
  }
  location ~ "^/pagespeed_static/" { }
  location ~ "^/ngx_pagespeed_beacon$" { }

  # [略]
}

這裡的 /var/ngx_pagespeed_cache 是給 PageSpeed 放置快取(暫存檔)的地方,若網站內容較多的話,需要的空間也會比較大,請自己找一個適合的地方來放置,並記得確認此目錄可讓 Nginx 伺服器讀取與寫入。

其餘的設定說明,請參考 PageSpeed 官方的文件

參考資料:Nginx 官方部落格Linode 的文件HeikoMamerowVultrPageSpeedGuideMR. 沙先生nostratech