這裡記錄在 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 原始碼目錄執行 configure
與 make
等指令即可,跟自己完全手動的做法類似。
若幸運的話,只要重新啟動 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 的文件、HeikoMamerow、Vultr、PageSpeedGuide、MR. 沙先生、nostratech