Nginx 是非同步框架的網頁伺服器,主要用於
- 反向代理 (reverse proxy) 能作為 API Gateway 進行後端分流
- 負載平衡 (load balancer) 和快取 (HTTP Cache) 可用於靜態網站架設
讓我們來開箱教學 Nginx 常用指令和 Nginx Config (Reverse Proxy、https) 與效能優化,另一篇文章會接著介紹 Nginx 管理與監控工具 Nginx Proxy Manager、Nginx GIXY、GoAccess。
Nginx 常用指令
Linux 是檔案系統,所以檔案要有系統的被放置
- 在 home 目錄底下的{使用者名稱}目錄: 因 linux 權限規劃嚴謹,檔案都有存取權限,建議發佈位置放在這個目錄下
- etc (配置檔)
- var(log)
安裝 Nginx
- linux 環境安裝 Nginx
- putty + ssh 連接至主機
- 升級系統相關套件與服務
sudo apt-get update
sudo apt-get install nginx
- windows 環境,在 Windows 只需要下載後解壓縮,即可執行
start nginx
使用。
Nginx 管理
在 Linux 主機上運用 Systemctl 做 Nginx 服務管理,在 Linux 中會使用 sudo systemctl
加上底下幾種指令:
- status (狀態)
- stop (停止)
- start (開始)
- enable (開機啟用)
- restart (重開)
底下的範例就是看 nginx 目前的狀態,接著列出有在開機預設開啟中的程式或服務,最後看目前有在執行的服務。
systemctl status nginx
systemctl list-unit-files | grep enabled
systemctl | grep running
Windows 曾遇過起來多個 processes 關不掉,所以建議修改配置後使用 nginx -s reload
。
nginx -s stop // fast shutdown
nginx -s quit // graceful shutdown
nginx -s reload // starting new worker processes with a new configuration, graceful shutdown of old worker processes
nginx -s reopen // re-opening log files
Nginx Log
Linux 的 log 會在 /var/log
:
- access log: 位置會在
/var/log/nginx/access.log
- error log: 位置會在
/var/log/nginx/error.log
查看 nginx 的 access log,tail -f /var/log/nginx/access.log
,這邊推薦可以使用 GoAccess 將資訊圖像化,並搭配 Linux 的 crontab 排程進行自動更新。
如果沒有管理 log 可能會佔蠻多硬碟空間 (查看硬碟使用情況: sudo du -sh /var/log/
),改善方法有以下幾種:
- 設定 Logrotate:
/etc/logrotate.d
- 指令清除
sudo find /var/log/ -type f -regex '.*\.[0-9]+\.gz$' -delete
- 關掉 Access Logging: 只要紀錄就會對 CPU 硬碟產生消耗
- 增加 buffer size 不要頻繁的製造 CPU 處理硬碟 IO,設定 flush=time 的時間定期處理
Nginx config 基礎設定
網站架設首先會需要放置檔案到 Nginx 伺服器
- FTP,架設的方式很多部落客都有教學
- jenkins,從版控抓 master branch 下來自動 build 及執行 shell 記得
BUILD_ID=DONTKILLME
設定接受請求的程式 (後端 API 或相關資源)
- 靜態的檔案,前端常見 SPA (single-page application) 專案,需上傳靜態網頁到 Server,並設定正確的路由才能夠回應給使用者
- 如果是 node.js 的後端,需要使用 PM2 這類的工具進行管理,也推薦使用 cluster mode 無痛升級效能
設定網站主要設定 server_name 指定網域,接著在 DNS 指向主機就大功告成。
- 靜態網站: 指向正確就可以了
- 動態網頁: 如 php 需要搭配 fastcgi 做相關反向代理的設定
server {
listen 80 default_server;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html;
try_files $uri /index.html;
}
server {
listen 80 default_server;
server_name example2.com www.example2.com;
root /var/www/example2.com;
index index.html;
try_files $uri /index.html;
}
常見的 Nginx Config
主要介紹下面幾項
- Nginx proxy_pass
- Nginx Reverse Proxy
- Nginx https
Nginx proxy_pass 設定
Nginx proxy_pass 的目的就是導流,透過不同的設定方式導流到不同的網站目錄,這就是反向代理的一個概念。
- 導流到根目錄:
test.com/app/xxxxx => http://192.168.1.100/xxxxx
location /app/ {
proxy_pass http://192.168.1.100/;
}
- 導流到特定目錄:
test.com/app/xxxxx => http://192.168.1.100/maped_dir/xxxxx
location /app/ {
proxy_pass http://192.168.1.100/maped_dir/;
}
反向代理 (Nginx Reverse Proxy)
網域往往只能連到一台入口主機,但當我們後端有很多網站及服務分配到多台主機時,這時候就需要透過路徑上的代理來轉發還有配置附載平衡,Nginx 就提供了這樣的功能,當然 AWS 上也有提供相關服務。
除此之外還可以做負載平衡,反向代理該設的參數要設對,proxy_http_version 1.1 請注意,有人有踩過雷了,另外附載平衡也很簡單,其中有幾種模式可以提供選擇,也可以進一步設定 health_check,讓 Nginx 去定時確認後端伺服器是否安好。
- least_conn 選擇最少連線數
- least_time 回應時間
- weight 倍數
upstream myapp1 {
server srv1.example.com weight=3;
server srv2.example.com;
server srv3.example.com;
least_conn;
}
server {
listen 80;
location / {
proxy_pass http://myapp1;
}
}
Nginx https 設定
https 可以使用免費的 Let’s Encrypt,在 https 安裝上推薦使用憑證機器人 自動更新 Let’s Encrypt 憑證
sudo certbot --nginx -d test.domain.com
sudo certbot delete --cert-name test.domain.com
sudo certbot renew --dry-run
執行指令後在檔案會看到 # managed by Certbot
註解,代表這部分設置就不需要我們維護,Digital Ocean 提供了很詳盡的教學,非常推薦。
接著寫好想要執行的 test.sh
檔並設定 Linux 排程定時更新 SSL 憑證,記得將檔案改好權限 chmod +x test.sh
,下面示範會產生資料夾:
#!/bin/bash
DIR=`date +%D`
DEST=~/test/$DIR
mkdir $DEST
自訂的排程時間則可以使用 crontab,使用 crontab -e
進行編輯,透過分鐘、小時、日、月、星期幾來進行週期設定。
- 譬如每個星期二的 4:00am 就可以寫成
0 4 * * 2 ~/test.sh
- 也可以使用縮寫
@daily ~/test.sh
相關縮寫如下:
- @hourly
0 * * * *
- @daily
0 0 * * *
- @weekly
0 0 * * 0
- @monthly
0 0 1 * *
- @yearly
0 0 1 1 *
防呆可以先用下面這個網站試寫:
https://crontab.guru/
Nginx 效能優化設定
Linux 設定檔在 /etc/nginx
,除了 epoll 可以從機制上影響效能外,也能從系統核心的設定優化效能。
- worker_processes 就是配合主機核心數,若是 4 核心就可以設置
worker_processes 4
- worker_rlimit_nofile 是可以開啟的檔案數量,像我以前公司伺服器就有需要提供圖磚的快取,設定大量的開啟檔案數量可以說是必須
- 快取,在 Nginx 也有提供 proxy_cache_path 的快取設定
- Gzip 壓縮,這個在很多地方都可以啟用,不一定需要在 Nginx 開啟
- client_max_body_size 限制檔案上傳大小
Connections 相關
- keepalive_requests: 預設值 100 可以邊壓測邊調整
- keepalive_timeout: 多久要切掉
- 反向代理的 keepalive,記得設定 proxy_http_version 1.1; proxy_set_header Connection “”;
加上相關限制
- limit_conn 譬如某些路由很佔頻寬就可以直接限制,不要影響其他快速的服務
- limit_rate 限速
- max_conns 如果 upstream 是比較弱的機台就建議設定一下
如果有需要用到 websocket,設定會不太一樣,參考官網文件需要配置如下。
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
Nginx Epoll
Nginx 在 Linux 的 IO 機制上有支援 epoll,所以在靜態網頁的效能上遠超過使用 select 機制的 apache,還有其他支援的機制可以參考官方文件。
- Apache Select (blocking):監考老師問學生,隨堂考試寫完沒,收集足夠後送批改。同時太多學生時,會需要等學生回覆,上限預設 1024。
- Nginx Epoll (non-blocking):老師不再問學生,學生完成後放講桌,收集足夠後送批改。所以伺服器端一定會有回覆,但不一定會有資料 (待批改清單),可能因為 timeout 回覆已過號請重新領取號碼牌,算是解決 C10K 的一種方式。
events {
use epoll;
worker_connections 1024;
multi_accept on;
}
Linux 系統核心設定
主要是編輯這個檔案 /etc/sysctl.conf
- sys.fs.file-max 最大開檔上限
sysctl -w fs.file-max=50000
(可以暫時測試重開機後會消失) - net.core.somaxconn: 能被 nginx queue 接受的最大連線數,可以設定成 512,超過還需要設定 listen 的 backlog 參數,因為除了 FreeBSD, DragonFly BSD, macOS 其他預設值是 511
- net.core.netdev_max_backlog: 網路卡的 backlog,加大會增加效能,但不了解網路卡的極限就容易出現錯誤 Orz
- nofile 也跟開檔數有關會在 /etc/security/limits.conf
Linux 底下的編輯器建議使用 nano,相對簡單,使用時就是使用指令加檔名 nano test.conf
,若是要修改權限外的檔案則要 sudo nano test.conf
,常見的如下,vi 和 vim 有區分指令模式跟輸入模式,操作概念較為複雜:
- vi
- vim
- nano
喜歡這篇文章,請幫忙拍拍手喔 🤣