四大步驟入門 Nginx 架站基礎設定
Nginx 搭配 Linux 系統 (Ubuntu) 架設網站是常見的解決方案,可實現反向代理 (reverse proxy)、負載平衡 (load balancer) 和快取 (Cache),Non Blocking IO 機制解決 C10K 的問題,接下來會用四個主要步驟介紹前端工程師常用的 Nginx Config 與相關指令。
- Linux、Windows 主機安裝與指令
- 伺服器管理與程式發佈
- Nginx Config 基礎設定: 反向代理 (proxy pass)、https 設定
- Nginx 效能優化設定 (HTTP 快取、Linux 系統核心設定)
如何在 Ubuntu 上架設 Nginx 網站伺服器? 如果是 SPA (single-page application),會需要放建置過的網頁檔到伺服器,並透過正確的路由能夠回應給使用者。
Linux、Windows 主機 Nginx 相關指令
Linux 主機設定由於是一個檔案系統,所以檔案要有系統的被放置
- 常用的會有在 home 目錄底下的{使用者名稱}目錄,因為 linux 的權限規劃的比較嚴謹,每個檔案都有相關的存取權限,建議發佈位置放在這個目錄下。
- etc (配置檔)
- var(log)
- 連接至主機,一般建議用 putty 免安裝版用 ssh 去連就可以了,如果虛擬機主人沒有動 port 預設都是可以連的,然後搭配不同家廠商的服務,大致都需要提供一些 key 或是配置檔。
- 升級系統相關套件與服務
1 | sudo apt-get update |
- 清理安裝檔
1 | sudo apt-get autoremove |
在 Windows 只需要下載後解壓縮,但在指令上比較特別,之前曾遇過多的 processes 關不掉的情況,所以建議在修改配置後都是使用 nginx -s reload
。
1 | nginx -s stop fast shutdown |
伺服器管理與程式發佈
在 Linux 主機上運用 Systemctl 做 Nginx 服務管理,當我們安裝了像是 Nginx、Jenkins、DB 後,會需要管理他們,在 Linux 中,我們一般會使用 sudo systemctl
加上底下幾種指令:
- status (狀態)
- stop (停止)
- start (開始)
- enable (開機啟用)
- restart (重開)
Nginx 伺服器管理
底下的範例就是看 nginx 目前的狀態,接著列出有在開機預設開啟中的程式或服務,最後看目前有在執行的服務。
1 | systemctl status nginx |
這些服務的 log 一般都會存在 /var/log
資料夾中,如果我們想看 nginx 的 access log,就可以使用 tail -f /var/log/nginx/access.log
,這裡有一點要注意的是如果沒有管理,log 可能會佔蠻多硬碟空間,這時候就可以使用 sudo du -sh /var/log/
來看到底用了多少,改善方法有以下兩種:
- 從設定檔中進行設定
/etc/logrotate.d
- 執行指令進行清除
sudo find /var/log/ -type f -regex '.*\.[0-9]+\.gz$' -delete
Nginx Log
關掉 Access Logging 只要紀錄就會對 CPU 硬碟產生消耗,或是增加 buffer size 不要頻繁的製造 CPU 處理硬碟 IO,設定 flush=time 的時間定期處理,當然直接停用最好
- access log 位置會在 /var/log/nginx/access.log,這邊推薦可以使用 GoAccess 將資訊圖像化,如果不想使用手工,可以搭配 Linux 的 crontab 排程進行自動更新。
- error log 位置會在 /var/log/nginx/error.log
程式發佈
- 放置檔案到伺服器
- FTP,架設的方式很多部落客都有教學
- jenkins,從版控抓 master branch 下來自動 build 及執行 shell 記得
BUILD_ID=DONTKILLME
- 接受請求的程式
- 靜態的檔案,這個部分推薦使用 nginx 就好了,方便又快速
- 如果是 node.js 的後端,需要使用 PM2 這類的工具進行管理,也推薦使用 cluster mode 無痛升級效能,node.js 在 Linux 上運行的好物
Nginx config 基礎設定
server_name 就是搭配我們的網域,接下來只要在 DNS 指向主機就大功告成。靜態的網站就較為單純,指向正確就可以了,但若是像 php 屬於動態網頁就還需要搭配 fastcgi 做相關反向代理的設定,
1 | server { |
Nginx Reverse Proxy 教學
反向代理 (Reverse Proxy): 網域往往只能連到一台入口主機,但當我們後端有很多網站及服務分配到多台主機時,這時候就需要透過路徑上的代理來轉發還有配置附載平衡,Nginx 就提供了這樣的功能,當然 AWS 上也有提供相關服務。
除此之外還可以做負載平衡,反向代理該設的參數要設對,proxy_http_version 1.1 請注意,有人有踩過雷了,另外附載平衡也很簡單,其中有幾種模式可以提供選擇,也可以進一步設定 health_check,讓 Nginx 去定時確認後端伺服器是否安好。
- least_conn 選擇最少連線數
- least_time 回應時間
- weight 倍數
1 | upstream myapp1 { |
proxy_pass 導流到根目錄
1 | location /app/ { |
proxy_pass 導流到特定目錄
1 | location /app/ { |
Nginx https 設定
https 可以使用免費的 Let’s Encrypt,在 https 安裝上推薦使用憑證機器人 自動更新 Let’s Encrypt 憑證
1 | sudo certbot --nginx -d test.domain.com |
跑過以後可以在檔案裡面可以看到 # managed by Certbot
的註解,代表這份配置檔的部分設置就不需要我們維護了,Digital Ocean 提供了很詳盡的教學,非常推薦。
接下來就是透過 Linux 排程設定定時更新憑證,首先寫好想要執行的 test.sh
檔,接著就可以透過設定排程來固定更新 SSL 憑證,記得將檔案改好權限 chmod +x test.sh
,下面示範會產生資料夾:
1 |
|
自訂的排程時間則可以使用 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,設定會不太一樣,參考官網文件需要配置如下。
1 | proxy_http_version 1.1; |
Nginx Epoll
Nginx 在 Linux 的 IO 機制上有支援 epoll,所以在靜態網頁的效能上遠超過使用 select 機制的 apache,而且只需要透過簡單配置即可使用,還有其他支援的機制可以參考官方文件。
- Apache Select (blocking):監考老師問學生,隨堂考試寫完沒,收集足夠後送批改。同時太多學生時,會需要等學生回覆,上限預設 1024。
- Nginx Epoll (non-blocking):老師不再問學生,學生完成後放講桌,收集足夠後送批改。所以伺服器端一定會有回覆,但不一定會有資料 (待批改清單),可能因為 timeout 回覆已過號請重新領取號碼牌,算是解決 C10K 的一種方式。
1 | events { |
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
Nginx 監控報表
目前我有使用過最簡單的方式有兩個:
- 透過 Elastic 提供的 Filebeat 和 Metricbeat 可以從狀態、日誌即時的去監控 Nginx
- 使用開源的 GoAccess 加上系統排程定時更新資料
Elastic Metricbeat
之前剛好使用過 Elastic 相關 Solution,發現透過簡單的配置就能夠知道目前伺服器的狀況,詳細的教學歡迎參考這篇文章: Elastic Metricbeat 搭配 Kibana 來監控 Nginx 伺服器狀態,就像下圖就是系統預設提供的樣板,可以簡單即時去監控 Nginx 的流量、記憶體、處理器當下使用量。
Metricbeat + Kibana
Elastic Filebeat
那如果需要分析 Log 並產生報表呢? 當然也可以透過 Elastic 相關 Solution,透過 Filebeat 傳送 Nginx Access Log 到 Elasticsearch 中,最後透過 Kibana 即時監看相關分析。
Filebeat + Kibana
GoAccess
如果不想要透過 Elastic,也有一套開源的工具 GoAccess 能夠分析 Log 並且產生報表的靜態網頁,不過由於是靜態網頁,所以使用上就需要透過設定作業系統排程來定時跑腳本更新頁面。
GoAccess Dashboard
Nginx GIXY
Gixy 是一個分析 Nginx 配置的自動化缺陷檢測工具,主要目標是避免錯誤和配置導致資安漏洞。
有一個練習用的 Repo vulnerable-nginx 可以拿來測試常見的問題。
- url normalization 改變 URL
- / 有差,盡量補上 slash 避免發生意外
- https://nginx.org/en/docs/http/ngx_http_core_module.html#location
- 反向代理到後端的 URL 有沒有路徑解析不一致
$uri: current URI in request, normalized
The value of $uri may change during request processing, e.g. when doing internal redirects, or when using index files.
使用 GIXY 分析結果如下:
1 | location /cats { |
1 | (base) PS C:\Users\yencheng> gixy C:\nginx-1.18.0\conf\nginx.conf |
喜歡這篇文章,請幫忙拍拍手喔 🤣