Nginx 搭配 WebP Server Go 製作簡易 WebP 圖片即時轉換伺服器

WebP 圖片格式是由 Google 主推的新一代圖片格式, 有比 JPEG 更好的壓縮品質與相較小的檔案大小, 而圖片品質還維持與 JPEG 人眼看不出來的損失, 在各家新的瀏覽器大多已經支援 WebP 格式, 但不包含 Safari 13, 不過 iOS 與 macOS 則需要等到 iOS 14 及 macOS 11 推出後支援, 現在的 Mac 用戶可能經歷過將網站圖片拖拉到桌面上, 圖片是 WebP 格式, 還得需要工具去轉換, 相信新一代 iOS 與 macOS 推出後將解決 WebP 支援的最後一塊拼圖, 雖說如此, macOS 上的 Chrome , Firefox 瀏覽器是可直接看到 WebP 圖片

既然 WebP 有這麼好的優點, 檔案小品質佳, 對於網站經營者來說可以減少頻寬支出, 所以各家 CDN 業者像是 Cloudflare 的 Polish 功能直接幫網站轉 WebP 無需變動網站程式或傳統 GIF / JPG / PNG...等檔案, 在支援 WebP 的瀏覽器輸出轉換 WebP 圖片, 在 Safari 13 輸出 原本的圖片, 那沒有 CDN 怎麼辦? 本文將利用 WebP Server Go 版本搭配 Nginx Web Server 建立一個即時轉換的代理伺服器

WebP Server Go


WebP Server Go 是由 Nova Kwok 為主要開發者, 以 Go 語言編寫的伺服器軟體, 另外也有其他電腦語言的版本, 這個專案在: https://github.com/webp-sh/webp_server_go, 可在此下載最新已編譯好的伺服器軟體或原始碼來使用

在看過原始碼後, WebP Server Go 會將原本的 JPG 圖片另存一個 .webp 副檔名的 WebP 格式圖片, 例如:
test.jpg.1598510600.webp
是的, 還加上了 Unix Timestamp (1598510600) 標記轉換時間, 如果你只要單純利用 WebP Server Go 轉圖, 可以直接立即使用伺服器軟體執行檔, 我因為想輸出 test.webp, 那麼就需要修改原始碼

目前的 WebP Server Go 0.2.0 版使用 Go 1.14 編譯, 而我的測試環境是 Debian Linux 10, 預設的 Golang 套件為 1.11, 需要較新的 Golang 套件, 還好已經有 golang-1.14-go 套件可用

安裝 Golang 1.14


apt-get -t buster-backports install golang-1.14-go

編譯器將安裝到/usr/lib/go-1.14/bin/目錄

下載 WebP Server Go 0.2.0


wget https://github.com/webp-sh/webp_server_go/archive/0.2.0.tar.gz
tar zxvf 0.2.0.tar.gz
cd webp_server_go-0.2.0


修改 webp-server.go, 避免啟動 WebP Server Go 自動更新功能升級到最新版, 免得後續修改白費
nano webp-server.go

尋找 go autoUpdate(), 改成 // go autoUpdate()讓自動更新無效

接著修改儲存 WebP 圖片的檔案名稱規則, 打開 helper.go 程式
nano helper.go


先在 import 模組下加上新的函數, 用於取得檔案名稱, 去掉副檔名
func fileNameWithoutExtension(fileName string) string {
return strings.TrimSuffix(fileName, filepath.Ext(fileName))
}

此段程式來自於 https://gist.github.com/ivanzoid/129460aa08aff72862a534ebe0a9ae30

尋找 func GenWebpAbs 函數, 以下是我修改過的函數
func GenWebpAbs(RawImagePath string, ExhaustPath string, ImgFilename string, reqURI string) (string, string) {
_, err := os.Stat(RawImagePath)
if err != nil {
log.Error(err.Error())
}
WebpFilename := fmt.Sprintf("%s.webp", fileNameWithoutExtension(ImgFilename))
cwd, _ := os.Getwd()

WebpAbsolutePath := path.Clean(path.Join(ExhaustPath, path.Dir(reqURI), WebpFilename))
return cwd, WebpAbsolutePath
}

修改完成後, 就可以編譯了
/usr/lib/go-1.14/bin/go build

完成編譯會有一個執行檔, 名為 webp_server_go

Nginx + WebP Server Go 服務設定


複製執行檔到系統目錄
cp webp_server_go /usr/local/bin/webp-server


輸出預設組態檔
mkdir /etc/webps
webp-server -dump-config > /etc/webps/config.json

修改設定檔
nano /etc/webps/config.json

以下是我的範例設定
{
"HOST": "127.0.0.1",
"PORT": "8080",
"QUALITY": "85",
"IMG_PATH": "/var/www/html",
"EXHAUST_PATH": "/var/www/html",
"ALLOWED_TYPES": ["jpg","png","jpeg"]
}

這個 JSON 檔案, HOST 為監聽位址, 例如 127.0.0.1 (localhost), 或是你內網IP位址
PORT 則是監聽埠號, 預設是 3333, 我用 Port 8080
QUALITY 是預設 WebP 品質, 參考 Cloudflare 使用 85, 最高 100 代表最好品質
IMG_PATH 圖片目錄, 通常設定跟 Web Server 的 Document Root 同個目錄
EXHAUST_PATH 為轉換好的 WebP 圖片儲存目錄
ALLOWED_TYPES 只允許轉換 JPEG, PNG...等MIME Type, 由於 WebP Server Go 尚未實作 GIF 動畫檔轉換, 故不使用 GIF

舉例網站圖片 https://example.com/image/test.jpg, Document Root 若是 /var/www/html, 那麼 test.jpg 會是在 /var/www/html/image/test.jpg, 當然也能依照你的使用情境來設定 EXHAUST_PATH, 這個設定值可以理解為 WebP Server Go 的快取目錄

輸出 systemd service 檔案
webp-server -dump-systemd > /lib/systemd/system/webp-server.service

以下是我的修改範例
[Unit]
Description=WebP Server Go
Documentation=https://github.com/webp-sh/webp_server_go
After=nginx.target

[Service]
Type=simple
StandardError=journal
WorkingDirectory=/var/www/html
ExecStart=/usr/local/bin/webp-server --config /etc/webps/config.json
Restart=always
RestartSec=3s

[Install]
WantedBy=multi-user.target

啟用 WebP Server Go 服務
systemctl enable webp-server

WebP Server Go 要在 Nginx Web Server 之後啟動, 暫且關掉 Nginx, 修改 nginx.conf 來讓 WebP Server Go 對圖片做轉換
service nginx stop

編輯 Nginx 設定檔
nano /etc/nginx/nginx.conf

以下是我的範例
    upstream  webps {
server 127.0.0.1:8080;
}

server {
listen 80;
server_name _;

location ~ \.(jpg|jpeg|png)$ {
proxy_pass http://webps;
add_header Vary "Accept";
}

location / {
root /var/www/html;
index index.html index.htm;
}

}

儲存後, 啟動 Nginx
service nginx start

接著啟動 WebP Server Go
service webp-server start


實際測試


這是我的測試照片 test.jpg, 檔案大小 1,576,997 Bytes, 寬高為 1200x1920px
Nginx 搭配 WebP Server Go 製作簡易 WebP 圖片即時轉換伺服器

利用 Chrome 瀏覽器檢視圖片
Nginx 搭配 WebP Server Go 製作簡易 WebP 圖片即時轉換伺服器
用開發人員工具檢視 HTTP Response, Content-Type 傳回 image/webp, 你可以注意到我 Request 的是 test.jpg 而且 Header Content-Length: 270296, 這個 WebP 圖片只有 270,296 Bytes! 與原檔 1,576,997 Bytes 差異頗大! 當然, 依照上述設定, WebP Server Go 會在 Document Root 目錄 /var/www/html 下建立 WebP 圖檔快取, 下次讀取就不用花到 700ms 了
2020-08-27 16:00 發佈
內文搜尋
X
評分
評分
複製連結
Mobile01提醒您
您目前瀏覽的是行動版網頁
是否切換到電腦版網頁呢?