Nginx Config 與常用指令教學 快速入門網站架設

me
林彥成
2019-07-13 | 5 min.
文章目錄
  1. 1. Nginx 常用指令
    1. 1.1. 安裝 Nginx
    2. 1.2. Nginx 管理
    3. 1.3. Nginx Log
  2. 2. Nginx config 基礎設定
  3. 3. 常見的 Nginx Config
    1. 3.1. Nginx proxy_pass 設定
    2. 3.2. 反向代理 (Nginx Reverse Proxy)
    3. 3.3. Nginx https 設定
  4. 4. Nginx 效能優化設定
    1. 4.1. Nginx Epoll
    2. 4.2. Linux 系統核心設定

Nginx 是非同步框架的網頁伺服器,主要用於

  • 反向代理 (reverse proxy) 能作為 API Gateway 進行後端分流
  • 負載平衡 (load balancer) 和快取 (HTTP Cache) 可用於靜態網站架設

讓我們來開箱教學 Nginx 常用指令和 Nginx Config (Reverse Proxy、https) 與效能優化,另一篇文章會接著介紹 Nginx 管理與監控工具 Nginx Proxy Manager、Nginx GIXY、GoAccess

Nginx 常用指令

Linux 是檔案系統,所以檔案要有系統的被放置

  1. 在 home 目錄底下的{使用者名稱}目錄: 因 linux 權限規劃嚴謹,檔案都有存取權限,建議發佈位置放在這個目錄下
  2. etc (配置檔)
  3. var(log)

安裝 Nginx

  1. linux 環境安裝 Nginx
  • putty + ssh 連接至主機
  • 升級系統相關套件與服務
1
2
sudo apt-get update
sudo apt-get install nginx
  1. windows 環境,在 Windows 只需要下載後解壓縮,即可執行 start nginx 使用。

Nginx 管理

在 Linux 主機上運用 Systemctl 做 Nginx 服務管理,在 Linux 中會使用 sudo systemctl 加上底下幾種指令:

  1. status (狀態)
  2. stop (停止)
  3. start (開始)
  4. enable (開機啟用)
  5. restart (重開)

底下的範例就是看 nginx 目前的狀態,接著列出有在開機預設開啟中的程式或服務,最後看目前有在執行的服務。

1
2
3
systemctl status nginx
systemctl list-unit-files | grep enabled
systemctl | grep running

Windows 曾遇過起來多個 processes 關不掉,所以建議修改配置後使用 nginx -s reload

1
2
3
4
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/),改善方法有以下幾種:

  1. 設定 Logrotate: /etc/logrotate.d
  2. 指令清除 sudo find /var/log/ -type f -regex '.*\.[0-9]+\.gz$' -delete
  3. 關掉 Access Logging: 只要紀錄就會對 CPU 硬碟產生消耗
  4. 增加 buffer size 不要頻繁的製造 CPU 處理硬碟 IO,設定 flush=time 的時間定期處理

Nginx config 基礎設定

網站架設首先會需要放置檔案到 Nginx 伺服器

  1. FTP,架設的方式很多部落客都有教學
  2. jenkins,從版控抓 master branch 下來自動 build 及執行 shell 記得 BUILD_ID=DONTKILLME

設定接受請求的程式 (後端 API 或相關資源)

  1. 靜態的檔案,前端常見 SPA (single-page application) 專案,需上傳靜態網頁到 Server,並設定正確的路由才能夠回應給使用者
  2. 如果是 node.js 的後端,需要使用 PM2 這類的工具進行管理,也推薦使用 cluster mode 無痛升級效能

設定網站主要設定 server_name 指定網域,接著在 DNS 指向主機就大功告成。

  • 靜態網站: 指向正確就可以了
  • 動態網頁: 如 php 需要搭配 fastcgi 做相關反向代理的設定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
1
2
3
location /app/ {
proxy_pass http://192.168.1.100/;
}
  • 導流到特定目錄: test.com/app/xxxxx => http://192.168.1.100/maped_dir/xxxxx
1
2
3
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 倍數
1
2
3
4
5
6
7
8
9
10
11
12
13
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 憑證

1
2
3
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,下面示範會產生資料夾:

1
2
3
4
#!/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,設定會不太一樣,參考官網文件需要配置如下。

1
2
3
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 的一種方式。
1
2
3
4
5
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

喜歡這篇文章,請幫忙拍拍手喔 🤣


share